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:
190: $sqlCatLang = (count($this->_options['categories']) > 0) ? " idcat IN ('" . implode("','", $this->_options['categories']) . "') AND " : '';
191:
192: $db = cRegistry::getDb();
193: $sql = "SELECT startidartlang, idcat FROM " . $cfg['tab']['cat_lang'] . " WHERE " . $sqlCatLang . " idlang=" . $this->_options['lang'];
194: $db->query($sql);
195:
196: while ($db->nextRecord()) {
197: $startId = $db->f('startidartlang');
198: if ($startId > 0) {
199: $this->_startArticles[$db->f('idcat')] = $startId;
200: }
201: }
202:
203:
204: $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 ';
205:
206: $sqlArtSpecs = (count($this->_options['artspecs']) > 0) ? " a.artspec IN ('" . implode("','", $this->_options['artspecs']) . "') AND " : '';
207: $sqlStartArticles = '';
208:
209: if (count($this->_startArticles) > 0) {
210: if ($this->_options['start'] == false) {
211: $sqlStartArticles = "a.idartlang NOT IN ('" . implode("','", $this->_startArticles) . "') AND ";
212: }
213:
214: if ($this->_options['startonly'] == true) {
215: $sqlStartArticles = "a.idartlang IN ('" . implode("','", $this->_startArticles) . "') AND ";
216: }
217: }
218:
219: if ($this->_options['startonly'] == true && count($this->_startArticles) == 0) {
220: return;
221: }
222:
223: $sql = "SELECT DISTINCT a.idartlang FROM " . $cfg['tab']['art_lang'] . " AS a, ";
224: $sql .= $cfg['tab']['art'] . " AS b";
225: $sql .= $sqlCat . $sqlStartArticles . $sqlArtSpecs . "b.idclient = '" . $this->_options['client'] . "' AND ";
226: $sql .= "a.idlang = '" . $this->_options['lang'] . "' AND " . "a.idart = b.idart";
227:
228: if ($this->_options['offlineonly'] == true) {
229: $sql .= " AND a.online = 0";
230: } elseif ($this->_options['offline'] == false) {
231: $sql .= " AND a.online = 1";
232: }
233:
234: $sql .= " ORDER BY a." . $this->_options['order'] . " " . $this->_options['direction'];
235:
236: if ((int) $this->_options['limit'] > 0) {
237: $sql .= " LIMIT " . cSecurity::toInteger($this->_options['limit']);
238: }
239:
240: if ((int) $this->_options['offset'] > 0) {
241: $sql .= " OFFSET " . cSecurity::toInteger($this->_options['offset']);
242: }
243:
244: $db->query($sql);
245:
246: while ($db->nextRecord()) {
247: $artLangId = $db->f('idartlang');
248: $this->_articles[] = new cApiArticleLanguage($artLangId);
249: }
250:
251:
252: cApiCecHook::execute('Contenido.ArticleCollector.Articles', array(
253: 'idart' => cRegistry::getArticleId(),
254: 'articles' => $this->_articles
255: ));
256: }
257:
258: 259: 260: 261: 262: 263: 264: 265:
266: public function startArticle() {
267: if (count($this->_startArticles) != 1) {
268: throw new cBadMethodCallException("Can not load start article due to multiple loaded start articles.");
269: }
270:
271: return new cApiArticleLanguage(current($this->_startArticles));
272: }
273:
274: 275: 276: 277: 278: 279:
280: public function nextArticle() {
281: $next = $this->current();
282: $this->next();
283:
284: if ($next instanceof cApiArticleLanguage) {
285: return $next;
286: }
287:
288: return false;
289: }
290:
291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302: 303:
304: public function setResultPerPage($resPerPage) {
305: if ($resPerPage > 0) {
306: if (is_array($this->_articles)) {
307: $this->_pages = array_chunk($this->_articles, $resPerPage);
308: } else {
309: $this->_pages = array();
310: }
311: }
312: }
313:
314: 315: 316: 317: 318: 319: 320: 321: 322: 323:
324: public function setPage($page) {
325: if (array_key_exists($page, $this->_pages)) {
326: $this->_articles = $this->_pages[$page];
327: }
328: }
329: 330: 331: 332: 333: 334: 335: 336:
337: public function seek($position) {
338: $this->_currentPosition = $position;
339:
340: if ($this->valid() === false) {
341: throw new cOutOfBoundsException("Invalid seek position: " . $position);
342: }
343: }
344:
345: 346: 347:
348: public function rewind() {
349: $this->_currentPosition = 0;
350: }
351:
352: 353: 354: 355: 356:
357: public function current() {
358: return $this->_articles[$this->_currentPosition];
359: }
360:
361: 362: 363: 364: 365:
366: public function key() {
367: return $this->_currentPosition;
368: }
369:
370: 371: 372:
373: public function next() {
374: ++$this->_currentPosition;
375: }
376:
377: 378: 379: 380: 381:
382: public function valid() {
383: return isset($this->_articles[$this->_currentPosition]);
384: }
385:
386: 387: 388: 389: 390: 391:
392: public function count() {
393: return count($this->_articles);
394: }
395:
396: 397: 398:
399: public function getStartArticles()
400: {
401: return $this->_startArticles;
402: }
403:
404: }
405: