Overview

Packages

  • Core
    • Authentication
    • Backend
    • Cache
    • CEC
    • Chain
    • ContentType
    • Database
    • Datatype
    • Debug
    • Exception
    • Frontend
      • Search
      • URI
      • Util
    • GenericDB
      • Model
    • GUI
      • HTML
    • I18N
    • LayoutHandler
    • Log
    • Security
    • Session
    • Util
    • Validation
    • Versioning
    • XML
  • Module
    • ContentSitemapHtml
    • ContentSitemapXml
    • ContentUserForum
    • NavigationMain
    • NavigationTop
  • mpAutoloaderClassMap
  • None
  • Plugin
    • ContentAllocation
    • CronjobOverview
    • FormAssistant
    • FrontendLogic
    • FrontendUsers
    • Linkchecker
    • ModRewrite
    • Newsletter
    • Repository
      • FrontendNavigation
      • KeywordDensity
    • SearchSolr
    • SmartyWrapper
    • UrlShortener
    • UserForum
    • Workflow
  • PluginManager
  • Setup
    • Form
    • GUI
    • Helper
      • Environment
      • Filesystem
      • MySQL
      • PHP
    • UpgradeJob

Classes

  • cApiPathresolveCacheHelper
  • cArray
  • cArticleCollector
  • cDirHandler
  • cFileHandler
  • cHTMLInputSelectElement
  • cIterator
  • cString
  • UI_Config_Table
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  • Todo
  1: <?php
  2: /**
  3:  * This file contains the array utility class.
  4:  *
  5:  * @package    Core
  6:  * @subpackage Util
  7:  * @version    SVN Revision $Rev:$
  8:  *
  9:  * @author     Dominik Ziegler
 10:  * @copyright  four for business AG <www.4fb.de>
 11:  * @license    http://www.contenido.org/license/LIZENZ.txt
 12:  * @link       http://www.4fb.de
 13:  * @link       http://www.contenido.org
 14:  */
 15: 
 16: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
 17: 
 18: /**
 19:  * The
 20:  * article collector returns you a list of articles, which destination you can
 21:  * choose.
 22:  * You have the ability to limit, sort and filter the article list.
 23:  *
 24:  * You can configure the article collector with an options array, which can include the
 25:  * following configuration.
 26:  *
 27:  * - idcat - category ID
 28:  * - categories - array with multiple category IDs
 29:  * - lang - language ID, active language if ommited
 30:  * - client - client ID, active client if ommited
 31:  * - artspecs - array of article specifications, which should be considered
 32:  * - offline - include offline article in the collection, defaults to false
 33:  * - offlineonly - only list offline articles, defaults to false
 34:  * - start - include start article in the collection, defaults to false
 35:  * - startonly - only list start articles, defaults to false
 36:  * - order - articles will be ordered by this property, defaults to created
 37:  * - direction - order direction, ASC or DESC for ascending/descending, defaults to DESC
 38:  * - limit - limit numbers of articles in collection, default to 0 (unlimited)
 39:  *
 40:  * TODO: Use generic DB instead of SQL queries
 41:  *
 42:  * @package Core
 43:  * @subpackage Util
 44:  */
 45: class cArticleCollector implements SeekableIterator, Countable {
 46: 
 47:     /**
 48:      * Options for the collector.
 49:      *
 50:      * @var array
 51:      */
 52:     protected $_options = array();
 53: 
 54:     /**
 55:      * Loaded articles.
 56:      *
 57:      * @var array
 58:      */
 59:     protected $_articles = array();
 60: 
 61:     /**
 62:      * Total paging data.
 63:      *
 64:      * @var array
 65:      */
 66:     protected $_pages = array();
 67: 
 68:     /**
 69:      * Start articles of the requested categories.
 70:      *
 71:      * @var array
 72:      */
 73:     protected $_startArticles = array();
 74: 
 75:     /**
 76:      * Current position for the iterator.
 77:      *
 78:      * @var int
 79:      */
 80:     protected $_currentPosition = 0;
 81: 
 82:     /**
 83:      * Constructor. If options are defined, the loading process is automatically
 84:      * initiated.
 85:      *
 86:      * @param array $options array with options for the collector (optional,
 87:      *            default: empty array)
 88:      */
 89:     public function __construct($options = array()) {
 90:         if (count($options) > 0) {
 91:             $this->setOptions($options);
 92:             $this->loadArticles();
 93:         }
 94:     }
 95: 
 96:     /**
 97:      * Setter for the collector options. Validates incoming options and sets the
 98:      * default of the missing options.
 99:      *
100:      * @param array $options array with option
101:      */
102:     public function setOptions($options) {
103:         if (isset($options['idcat']) && !isset($options['categories'])) {
104:             $options['categories'] = array(
105:                     $options['idcat']
106:             );
107:         }
108: 
109:         if (isset($options['categories']) === false) {
110:             $options['categories'] = array();
111:         }
112: 
113:         if (isset($options['lang']) === false) {
114:             $options['lang'] = cRegistry::getLanguageId();
115:         }
116: 
117:         if (isset($options['client']) === false) {
118:             $options['client'] = cRegistry::getClientId();
119:         }
120: 
121:         if (isset($options['start']) === false) {
122:             $options['start'] = false;
123:         }
124: 
125:         if (isset($options['startonly']) === false) {
126:             $options['startonly'] = false;
127:         }
128: 
129:         if (isset($options['offline']) === false) {
130:             $options['offline'] = false;
131:         }
132: 
133:         if (isset($options['offlineonly']) === false) {
134:             $options['offlineonly'] = false;
135:         }
136: 
137:         switch ($options['order']) {
138:             case 'sortsequence':
139:                 $options['order'] = 'artsort';
140:                 break;
141: 
142:             case 'modificationdate':
143:                 $options['order'] = 'lastmodified';
144:                 break;
145: 
146:             case 'publisheddate':
147:                 $options['order'] = 'published';
148:                 break;
149: 
150:             case 'creationdate':
151:             default:
152:                 $options['order'] = 'created';
153:                 break;
154:         }
155: 
156:         if (isset($options['artspecs']) === false) {
157:             $options['artspecs'] = array();
158:         }
159: 
160:         if (isset($options['direction']) === false) {
161:             $options['direction'] = 'DESC';
162:         }
163: 
164:         if (isset($options['limit']) === false) {
165:             $options['limit'] = 0;
166:         }
167: 
168:         $this->_options = $options;
169:     }
170: 
171:     /**
172:      * Executes the article search with the given options.
173:      *
174:      * @throws cUnexpectedValueException
175:      */
176:     public function loadArticles() {
177:         $this->_articles = array();
178: 
179:         $cfg = cRegistry::getConfig();
180: 
181:         $sqlCat = (count($this->_options['categories']) > 0)? " idcat IN ('" . implode("','", $this->_options['categories']) . "') AND " : '';
182: 
183:         $db = cRegistry::getDb();
184:         $sql = "SELECT startidartlang, idcat FROM " . $cfg['tab']['cat_lang'] . " WHERE " . $sqlCat . " idlang=" . $this->_options['lang'];
185:         $db->query($sql);
186: 
187:         while ($db->nextRecord()) {
188:             $startId = $db->f('startidartlang');
189:             if ($startId > 0) {
190:                 $this->_startArticles[$db->f('idcat')] = $startId;
191:                 if ($this->_options['startonly'] == true) {
192:                     $this->_articles[] = new cApiArticleLanguage($startId);
193:                 }
194:             }
195:         }
196: 
197:         if (count($this->_articles) > 0) {
198:             return;
199:         }
200: 
201:         $sqlCat = (count($this->_options['categories']) > 0)? " c.idcat IN ('" . implode("','", $this->_options['categories']) . "') AND b.idart = c.idart AND " : '';
202:         $sqlArtSpecs = (count($this->_options['artspecs']) > 0)? " a.artspec IN ('" . implode("','", $this->_options['artspecs']) . "') AND " : '';
203: 
204:         if ($this->_options['start'] == false && count($this->_startArticles) > 0) {
205:             $sqlStartArticles = "a.idartlang NOT IN ('" . implode("','", $this->_startArticles) . "') AND ";
206:         }
207: 
208:         $sql = "SELECT DISTINCT a.idartlang FROM " . $cfg['tab']['art_lang'] . " AS a, " . $cfg['tab']['art'] . " AS b, " . $cfg['tab']['cat_art'] . " AS c " . " WHERE " . $sqlCat . $sqlStartArticles . $sqlArtSpecs . "b.idclient = '" . $this->_options['client'] . "' AND " . "a.idlang = '" . $this->_options['lang'] . "' AND " . "a.idart = b.idart";
209: 
210:         if ($this->_options['offlineonly'] == true) {
211:             $sql .= " AND a.online = 0";
212:         } elseif ($this->_options['offline'] == false) {
213:             $sql .= " AND a.online = 1";
214:         }
215: 
216:         $sql .= " ORDER BY a." . $this->_options['order'] . " " . $this->_options['direction'];
217: 
218:         if ((int) $this->_options['limit'] > 0) {
219:             $sql .= " LIMIT " . $this->_options['limit'];
220:         }
221: 
222:         $db->query($sql);
223: 
224:         while ($db->nextRecord()) {
225:             $artLangId = $db->f('idartlang');
226:             $this->_articles[] = new cApiArticleLanguage($artLangId);
227:         }
228:     }
229: 
230:     /**
231:      * Compatibility method for old ArticleCollection class. Returns the start
232:      * article of a category. Does work only if one category was requested.
233:      *
234:      * @return cApiArticleLanguage
235:      * @throws cBadMethodCallException
236:      */
237:     public function startArticle() {
238:         if (count($this->_startArticles) != 1) {
239:             throw new cBadMethodCallException("Can not load start article due to multiple loaded start articles.");
240:         }
241: 
242:         return new cApiArticleLanguage(current($this->_startArticles));
243:     }
244: 
245:     /**
246:      * Compatibility method for old ArticleCollection class. Returns the next
247:      * article.
248:      *
249:      * @return bool cApiArticleLanguage
250:      */
251:     public function nextArticle() {
252:         $next = $this->current();
253:         $this->next();
254: 
255:         if ($next instanceof cApiArticleLanguage) {
256:             return $next;
257:         }
258: 
259:         return false;
260:     }
261: 
262:     /**
263:      * Compatibility method for old ArticleCollection. Split the article results
264:      * into pages of a given size.
265:      * Example: Article Collection with 5 articles
266:      * [0] => 250 [1] => 251 [2] => 253 [3] => 254 [4] => 255
267:      * $collection->setResultPerPage(2)
268:      * Would split the results into 3 pages
269:      * [0] => [0] => 250 [1] => 251 [1] => [0] => 253 [1] => 254 [2] => [0] =>
270:      * 255
271:      * A page can be selected with $collection->setPage(int page)
272:      *
273:      * @param int $resPerPage
274:      * @return void
275:      */
276:     public function setResultPerPage($resPerPage) {
277:         if ($resPerPage > 0) {
278:             if (is_array($this->_articles)) {
279:                 $this->_pages = array_chunk($this->_articles, $resPerPage);
280:             } else {
281:                 $this->_pages = array();
282:             }
283:         }
284:     }
285: 
286:     /**
287:      * Compatibility method for old ArticleCollection. Select a page if the
288:      * results was divided before.
289:      * $collection->setResultPerPage(2); $collection->setPage(1);
290:      * // Iterate through all articles of page two while ($art =
291:      * $collection->nextArticle()) { ... }
292:      *
293:      * @param int $page The page of the article collection
294:      */
295:     public function setPage($page) {
296:         if (is_array($this->_pages[$page])) {
297:             $this->_articles = $this->_pages[$page];
298:         }
299:     }
300: 
301:     /**
302:      * Seeks a specific position in the loaded articles.
303:      *
304:      * @param int $position position to load
305:      * @throws cOutOfBoundsException
306:      */
307:     public function seek($position) {
308:         $this->_currentPosition = $position;
309: 
310:         if ($this->valid() === false) {
311:             throw new cOutOfBoundsException("Invalid seek position: " . $position);
312:         }
313:     }
314: 
315:     /**
316:      * Method "rewind" of the implemented iterator.
317:      */
318:     public function rewind() {
319:         $this->_currentPosition = 0;
320:     }
321: 
322:     /**
323:      * Method "current" of the implemented iterator.
324:      *
325:      * @return mixed
326:      */
327:     public function current() {
328:         return $this->_articles[$this->_currentPosition];
329:     }
330: 
331:     /**
332:      * Method "key" of the implemented iterator.
333:      *
334:      * @return int mixed
335:      */
336:     public function key() {
337:         return $this->_currentPosition;
338:     }
339: 
340:     /**
341:      * Method "next" of the implemented iterator.
342:      */
343:     public function next() {
344:         ++$this->_currentPosition;
345:     }
346: 
347:     /**
348:      * Method "valid" of the implemented iterator.
349:      *
350:      * @return bool
351:      */
352:     public function valid() {
353:         return isset($this->_articles[$this->_currentPosition]);
354:     }
355: 
356:     /**
357:      * Method "count" of the implemented Countable interface. Returns the amount
358:      * of all loaded articles.
359:      *
360:      * @return int
361:      */
362:     public function count() {
363:         return count($this->_articles);
364:     }
365: 
366: }
CMS CONTENIDO 4.9.0 API documentation generated by ApiGen 2.8.0