1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
13:
14: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
15:
16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42:
43: class cArticleCollector implements SeekableIterator, Countable {
44:
45: 46: 47: 48: 49:
50: protected $_options = array();
51:
52: 53: 54: 55: 56:
57: protected $_articles = array();
58:
59: 60: 61: 62: 63:
64: protected $_pages = array();
65:
66: 67: 68: 69: 70:
71: protected $_startArticles = array();
72:
73: 74: 75: 76: 77:
78: protected $_currentPosition = 0;
79:
80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90:
91: public function __construct($options = array()) {
92: $this->setOptions($options);
93: $this->loadArticles();
94: }
95:
96: 97: 98: 99: 100: 101: 102:
103: public function setOptions($options) {
104: if (isset($options['idcat']) && !isset($options['categories'])) {
105: $options['categories'] = array(
106: $options['idcat']
107: );
108: }
109:
110: if (isset($options['categories']) === false) {
111: $options['categories'] = array();
112: }
113:
114: if (isset($options['lang']) === false) {
115: $options['lang'] = cRegistry::getLanguageId();
116: }
117:
118: if (isset($options['client']) === false) {
119: $options['client'] = cRegistry::getClientId();
120: }
121:
122: if (isset($options['start']) === false) {
123: $options['start'] = false;
124: }
125:
126: if (isset($options['startonly']) === false) {
127: $options['startonly'] = false;
128: }
129:
130: if (isset($options['offline']) === false) {
131: $options['offline'] = false;
132: }
133:
134: if (isset($options['offlineonly']) === false) {
135: $options['offlineonly'] = false;
136: }
137:
138: switch ($options['order']) {
139: case 'sortsequence':
140: $options['order'] = 'artsort';
141: break;
142:
143: case 'title':
144: $options['order'] = 'title';
145: break;
146:
147: case 'modificationdate':
148: $options['order'] = 'lastmodified';
149: break;
150:
151: case 'publisheddate':
152: $options['order'] = 'published';
153: break;
154:
155: case 'creationdate':
156: default:
157: $options['order'] = 'created';
158: break;
159: }
160:
161: if (isset($options['artspecs']) === false) {
162: $options['artspecs'] = array();
163: }
164:
165: if (isset($options['direction']) === false) {
166: $options['direction'] = 'DESC';
167: }
168:
169: if (isset($options['limit']) === false) {
170: $options['limit'] = 0;
171: }
172:
173: if (isset($options['offset']) === false) {
174: $options['offset'] = 0;
175: }
176:
177: $this->_options = $options;
178: }
179:
180: 181: 182: 183: 184:
185: public function loadArticles() {
186: $this->_articles = array();
187:
188: $cfg = cRegistry::getConfig();
189: $db = cRegistry::getDb();
190:
191: $sql = "SELECT startidartlang, idcat
192: FROM " . $cfg['tab']['cat_lang'] . "
193: WHERE idlang=" . $this->_options['lang'];
194: if (count($this->_options['categories']) > 0) {
195: $sql .= " AND idcat IN ('" . implode("','", $this->_options['categories']) . "')";
196: }
197: $db->query($sql);
198:
199: while ($db->nextRecord()) {
200: $startId = $db->f('startidartlang');
201: if ($startId > 0) {
202: $this->_startArticles[$db->f('idcat')] = $startId;
203: }
204: }
205:
206:
207: $sqlCat = (count($this->_options['categories']) > 0) ? ", " . $cfg['tab']['cat_art'] . " AS c WHERE c.idcat IN ('" . implode("','", $this->_options['categories']) . "') AND b.idart = c.idart AND " : ' WHERE ';
208:
209: $sqlArtSpecs = (count($this->_options['artspecs']) > 0) ? " a.artspec IN ('" . implode("','", $this->_options['artspecs']) . "') AND " : '';
210: $sqlStartArticles = '';
211:
212: if (count($this->_startArticles) > 0) {
213: if ($this->_options['start'] == false) {
214: $sqlStartArticles = "a.idartlang NOT IN ('" . implode("','", $this->_startArticles) . "') AND ";
215: }
216:
217: if ($this->_options['startonly'] == true) {
218: $sqlStartArticles = "a.idartlang IN ('" . implode("','", $this->_startArticles) . "') AND ";
219: }
220: }
221:
222: if ($this->_options['startonly'] == true && count($this->_startArticles) == 0) {
223: return;
224: }
225:
226: $sql = "SELECT DISTINCT a.idartlang FROM " . $cfg['tab']['art_lang'] . " AS a, ";
227: $sql .= $cfg['tab']['art'] . " AS b";
228: $sql .= $sqlCat . $sqlStartArticles . $sqlArtSpecs . "b.idclient = '" . $this->_options['client'] . "' AND ";
229: $sql .= "a.idlang = '" . $this->_options['lang'] . "' AND " . "a.idart = b.idart";
230:
231: if ($this->_options['offlineonly'] == true) {
232: $sql .= " AND a.online = 0";
233: } elseif ($this->_options['offline'] == false) {
234: $sql .= " AND a.online = 1";
235: }
236:
237: $sql .= " ORDER BY a." . $this->_options['order'] . " " . $this->_options['direction'];
238:
239: if ((int) $this->_options['limit'] > 0) {
240: $sql .= " LIMIT " . cSecurity::toInteger($this->_options['limit']);
241: }
242:
243: if ((int) $this->_options['offset'] > 0) {
244: $sql .= " OFFSET " . cSecurity::toInteger($this->_options['offset']);
245: }
246:
247: $db->query($sql);
248:
249: while ($db->nextRecord()) {
250: $artLangId = $db->f('idartlang');
251: $this->_articles[] = new cApiArticleLanguage($artLangId);
252: }
253:
254:
255: cApiCecHook::execute('Contenido.ArticleCollector.Articles', array(
256: 'idart' => cRegistry::getArticleId(),
257: 'articles' => $this->_articles
258: ));
259: }
260:
261: 262: 263: 264: 265: 266: 267: 268:
269: public function startArticle() {
270: if (count($this->_startArticles) != 1) {
271: throw new cBadMethodCallException("Can not load start article due to multiple loaded start articles.");
272: }
273:
274: return new cApiArticleLanguage(current($this->_startArticles));
275: }
276:
277: 278: 279: 280: 281: 282:
283: public function nextArticle() {
284: $next = $this->current();
285: $this->next();
286:
287: if ($next instanceof cApiArticleLanguage) {
288: return $next;
289: }
290:
291: return false;
292: }
293:
294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306:
307: public function setResultPerPage($resPerPage) {
308: if ($resPerPage > 0) {
309: if (is_array($this->_articles)) {
310: $this->_pages = array_chunk($this->_articles, $resPerPage);
311: } else {
312: $this->_pages = array();
313: }
314: }
315: }
316:
317: 318: 319: 320: 321: 322: 323: 324: 325: 326:
327: public function setPage($page) {
328: if (array_key_exists($page, $this->_pages)) {
329: $this->_articles = $this->_pages[$page];
330: }
331: }
332: 333: 334: 335: 336: 337: 338: 339:
340: public function seek($position) {
341: $this->_currentPosition = $position;
342:
343: if ($this->valid() === false) {
344: throw new cOutOfBoundsException("Invalid seek position: " . $position);
345: }
346: }
347:
348: 349: 350:
351: public function rewind() {
352: $this->_currentPosition = 0;
353: }
354:
355: 356: 357: 358: 359:
360: public function current() {
361: return $this->_articles[$this->_currentPosition];
362: }
363:
364: 365: 366: 367: 368:
369: public function key() {
370: return $this->_currentPosition;
371: }
372:
373: 374: 375:
376: public function next() {
377: ++$this->_currentPosition;
378: }
379:
380: 381: 382: 383: 384:
385: public function valid() {
386: return isset($this->_articles[$this->_currentPosition]);
387: }
388:
389: 390: 391: 392: 393: 394:
395: public function count() {
396: return count($this->_articles);
397: }
398:
399: 400: 401:
402: public function getStartArticles()
403: {
404: return $this->_startArticles;
405: }
406:
407: }
408: