1: <?php
2: /**
3: * This file contains the QPaginatedControl and QDataBindException class.
4: *
5: * @package Controls
6: */
7:
8: /**
9: * @package Controls
10: * @property string $Noun Name of the items which are being paginated (book, movie, post etc.)
11: * @property string $NounPlural Plural form of name of the items which are being paginated (books, movies, posts etc.)
12: * @property QPaginatorBase $Paginator
13: * @property QPaginatorBase $PaginatorAlternate
14: * @property boolean $UseAjax
15: * @property integer $ItemsPerPage is how many items you want to display per page when Pagination is enabled
16: * @property integer $TotalItemCount is the total number of items in the ENTIRE recordset -- only used when Pagination is enabled
17: * @property mixed $DataSource is an array of anything. THIS MUST BE SET EVERY TIME (DataSource does NOT persist from postback to postback
18: * @property-read mixed $LimitClause
19: * @property-read mixed $LimitInfo is what should be passed in to the LIMIT clause of the sql query that retrieves the array of items from the database
20: * @property-read integer $ItemCount
21: * @property integer $PageNumber is the current page number you are viewing
22: * @property-read integer $PageCount
23: * @property-read integer $ItemsOffset Current offset of Items from the result
24: */
25: abstract class QPaginatedControl extends QControl {
26: use QDataBinder;
27:
28: // APPEARANCE
29: /** @var string Name of the items which are being paginated (books, movies, posts etc.) */
30: protected $strNoun;
31: /** @var string Plural form of name of the items which are being paginated (books, movies, posts etc.) */
32: protected $strNounPlural;
33:
34: // BEHAVIOR
35: /** @var null|QPaginator Paginator at the top */
36: protected $objPaginator = null;
37: /** @var null|QPaginator Paginator at the bottom */
38: protected $objPaginatorAlternate = null;
39: /** @var bool Determines whether this QDataGrid wll use AJAX or not */
40: protected $blnUseAjax = true;
41:
42: // MISC
43: /** @var array DataSource from which the items are picked and rendered */
44: protected $objDataSource;
45:
46: // SETUP
47: /** @var bool Is this paginator a block element? */
48: protected $blnIsBlockElement = true;
49:
50: /**
51: * @param QControl|QControlBase|QForm $objParentObject
52: * @param null|string $strControlId
53: *
54: * @throws Exception
55: * @throws QCallerException
56: */
57: public function __construct($objParentObject, $strControlId = null) {
58: parent::__construct($objParentObject, $strControlId);
59:
60: $this->strNoun = QApplication::Translate('item');
61: $this->strNounPlural = QApplication::Translate('items');
62: }
63:
64: // PaginatedControls should (in general) never have anything that ever needs to be validated -- so this always
65: // returns true.
66: public function Validate() {
67: return true;
68: }
69:
70: public function DataBind() {
71: // Run the DataBinder (if applicable)
72: if (($this->objDataSource === null) && ($this->HasDataBinder()) && (!$this->blnRendered))
73: {
74: try {
75: $this->CallDataBinder();
76: } catch (QCallerException $objExc) {
77: $objExc->IncrementOffset();
78: throw $objExc;
79: }
80:
81: if ($this->objPaginator && $this->PageNumber > $this->PageCount) {
82: $this->PageNumber = max($this->PageCount,1);
83: }
84: }
85: }
86:
87: /////////////////////////
88: // Public Properties: GET
89: /////////////////////////
90: /**
91: * PHP magic method
92: * @param string $strName Property name
93: *
94: * @return mixed
95: * @throws Exception|QCallerException
96: */
97: public function __get($strName) {
98: switch ($strName) {
99: // APPEARANCE
100: case "Noun": return $this->strNoun;
101: case "NounPlural": return $this->strNounPlural;
102:
103: // BEHAVIOR
104: case "Paginator": return $this->objPaginator;
105: case "PaginatorAlternate": return $this->objPaginatorAlternate;
106: case "UseAjax": return $this->blnUseAjax;
107: case "ItemsPerPage":
108: if ($this->objPaginator)
109: return $this->objPaginator->ItemsPerPage;
110: else
111: return null;
112: case "ItemsOffset":
113: if ($this->objPaginator)
114: return ($this->objPaginator->PageNumber - 1) * $this->objPaginator->ItemsPerPage;
115: else
116: return null;
117: case "TotalItemCount":
118: if ($this->objPaginator)
119: return $this->objPaginator->TotalItemCount;
120: else
121: return null;
122:
123: // MISC
124: case "DataSource": return $this->objDataSource;
125: case "LimitClause":
126: if ($this->objPaginator) {
127: // if ($this->objPaginator->TotalItemCount > 0) {
128: $intOffset = $this->ItemsOffset;
129: return QQ::LimitInfo($this->objPaginator->ItemsPerPage, $intOffset);
130: // }
131: }
132: return null;
133: case "LimitInfo":
134: if ($this->objPaginator) {
135: // if ($this->objPaginator->TotalItemCount > 0) {
136: $intOffset = $this->ItemsOffset;
137: return $intOffset . ',' . $this->objPaginator->ItemsPerPage;
138: // }
139: }
140: return null;
141: case "ItemCount": return count($this->objDataSource);
142:
143: case 'PageNumber':
144: if ($this->objPaginator)
145: return $this->objPaginator->PageNumber;
146: else
147: return null;
148:
149: case 'PageCount':
150: if ($this->objPaginator)
151: return $this->objPaginator->PageCount;
152: else
153: return null;
154:
155: default:
156: try {
157: return parent::__get($strName);
158: } catch (QCallerException $objExc) {
159: $objExc->IncrementOffset();
160: throw $objExc;
161: }
162: }
163: }
164:
165:
166:
167:
168:
169: /////////////////////////
170: // Public Properties: SET
171: /////////////////////////
172: public function __set($strName, $mixValue) {
173: switch ($strName) {
174: // APPEARANCE
175: case "Noun":
176: try {
177: $this->strNoun = QType::Cast($mixValue, QType::String);
178: $this->blnModified = true;
179: break;
180: } catch (QInvalidCastException $objExc) {
181: $objExc->IncrementOffset();
182: throw $objExc;
183: }
184: case "NounPlural":
185: try {
186: $this->strNounPlural = QType::Cast($mixValue, QType::String);
187: $this->blnModified = true;
188: break;
189: } catch (QInvalidCastException $objExc) {
190: $objExc->IncrementOffset();
191: throw $objExc;
192: }
193:
194: // BEHAVIOR
195: case "Paginator":
196: try {
197: $this->objPaginator = QType::Cast($mixValue, 'QPaginatorBase');
198: if ($this->objPaginator) {
199: if ($this->objPaginator->Form->FormId != $this->Form->FormId)
200: throw new QCallerException('The assigned paginator must belong to the same form that this control belongs to.');
201: $this->objPaginator->SetPaginatedControl($this);
202: }
203: $this->blnModified = true;
204: break;
205: } catch (QInvalidCastException $objExc) {
206: $objExc->IncrementOffset();
207: throw $objExc;
208: }
209:
210: case "PaginatorAlternate":
211: try {
212: $this->objPaginatorAlternate = QType::Cast($mixValue, 'QPaginatorBase');
213: if ($this->objPaginatorAlternate->Form->FormId != $this->Form->FormId)
214: throw new QCallerException('The assigned paginator must belong to the same form that this control belongs to.');
215: $this->objPaginatorAlternate->SetPaginatedControl($this);
216: $this->blnModified = true;
217: break;
218: } catch (QInvalidCastException $objExc) {
219: $objExc->IncrementOffset();
220: throw $objExc;
221: }
222:
223: case "UseAjax":
224: try {
225: $this->blnUseAjax = QType::Cast($mixValue, QType::Boolean);
226:
227: if ($this->objPaginator)
228: $this->objPaginator->UseAjax = $this->blnUseAjax;
229: if ($this->objPaginatorAlternate)
230: $this->objPaginatorAlternate->UseAjax = $this->blnUseAjax;
231:
232: $this->blnModified = true;
233: break;
234: } catch (QInvalidCastException $objExc) {
235: $objExc->IncrementOffset();
236: throw $objExc;
237: }
238: case "ItemsPerPage":
239: if ($this->objPaginator) {
240: try {
241: $intItemsPerPage = QType::Cast($mixValue, QType::Integer);
242: $this->objPaginator->ItemsPerPage = $intItemsPerPage;
243:
244: if ($this->objPaginatorAlternate) {
245: $this->objPaginatorAlternate->ItemsPerPage = $intItemsPerPage;
246: }
247:
248: $this->blnModified = true;
249: break;
250: } catch (QCallerException $objExc) {
251: $objExc->IncrementOffset();
252: throw $objExc;
253: }
254: } else
255: throw new QCallerException('Setting ItemsPerPage requires a Paginator to be set');
256: case "TotalItemCount":
257: if ($this->objPaginator) {
258: try {
259: $intTotalCount = QType::Cast($mixValue, QType::Integer);
260: $this->objPaginator->TotalItemCount = $intTotalCount;
261:
262: if ($this->objPaginatorAlternate) {
263: $this->objPaginatorAlternate->TotalItemCount = $intTotalCount;
264: }
265:
266: $this->blnModified = true;
267: break;
268: } catch (QCallerException $objExc) {
269: $objExc->IncrementOffset();
270: throw $objExc;
271: }
272: } else
273: throw new QCallerException('Setting TotalItemCount requires a Paginator to be set');
274:
275: // MISC
276: case "DataSource":
277: $this->objDataSource = $mixValue;
278: $this->blnModified = true;
279: break;
280:
281: case "PageNumber":
282: if ($this->objPaginator) {
283: try {
284: $intPageNumber = QType::Cast($mixValue, QType::Integer);
285: $this->objPaginator->PageNumber = $intPageNumber;
286:
287: if ($this->objPaginatorAlternate) {
288: $this->objPaginatorAlternate->PageNumber = $intPageNumber;
289: }
290: $this->blnModified = true;
291: break;
292: } catch (QCallerException $objExc) {
293: $objExc->IncrementOffset();
294: throw $objExc;
295: }
296: } else
297: throw new QCallerException('Setting PageNumber requires a Paginator to be set');
298:
299: default:
300: try {
301: parent::__set($strName, $mixValue);
302: break;
303: } catch (QCallerException $objExc) {
304: $objExc->IncrementOffset();
305: throw $objExc;
306: }
307: }
308: }
309: }