Overview

Packages

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

Classes

  • cApiAction
  • cApiActionCollection
  • cApiActionlog
  • cApiActionlogCollection
  • cApiArea
  • cApiAreaCollection
  • cApiArticle
  • cApiArticleCollection
  • cApiArticleLanguage
  • cApiArticleLanguageCollection
  • cApiArticleLanguageVersion
  • cApiArticleLanguageVersionCollection
  • cApiArticleSpecification
  • cApiArticleSpecificationCollection
  • cApiCategory
  • cApiCategoryArticle
  • cApiCategoryArticleCollection
  • cApiCategoryCollection
  • cApiCategoryLanguage
  • cApiCategoryLanguageCollection
  • cApiCategoryTree
  • cApiCategoryTreeCollection
  • cApiClient
  • cApiClientCollection
  • cApiClientLanguage
  • cApiClientLanguageCollection
  • cApiCommunication
  • cApiCommunicationCollection
  • cApiContainer
  • cApiContainerCollection
  • cApiContainerConfiguration
  • cApiContainerConfigurationCollection
  • cApiContent
  • cApiContentCollection
  • cApiContentVersion
  • cApiContentVersionCollection
  • cApiDbfs
  • cApiDbfsCollection
  • cApiFile
  • cApiFileCollection
  • cApiFileInformation
  • cApiFileInformationCollection
  • cApiFrameFile
  • cApiFrameFileCollection
  • cApiFrontendGroup
  • cApiFrontendGroupCollection
  • cApiFrontendGroupMember
  • cApiFrontendGroupMemberCollection
  • cApiFrontendPermission
  • cApiFrontendPermissionCollection
  • cApiFrontendUser
  • cApiFrontendUserCollection
  • cApiGroup
  • cApiGroupCollection
  • cApiGroupMember
  • cApiGroupMemberCollection
  • cApiGroupProperty
  • cApiGroupPropertyCollection
  • cApiInUse
  • cApiInUseCollection
  • cApiIso3166
  • cApiIso3166Collection
  • cApiIso6392
  • cApiIso6392Collection
  • cApiKeyword
  • cApiKeywordCollection
  • cApiLanguage
  • cApiLanguageCollection
  • cApiLayout
  • cApiLayoutCollection
  • cApiMailLog
  • cApiMailLogCollection
  • cApiMailLogSuccess
  • cApiMailLogSuccessCollection
  • cApiMetaTag
  • cApiMetaTagCollection
  • cApiMetaTagVersion
  • cApiMetaTagVersionCollection
  • cApiMetaType
  • cApiMetaTypeCollection
  • cApiModule
  • cApiModuleCollection
  • cApiNavMain
  • cApiNavMainCollection
  • cApiNavSub
  • cApiNavSubCollection
  • cApiOnlineUser
  • cApiOnlineUserCollection
  • cApiPathresolveCache
  • cApiPathresolveCacheCollection
  • cApiProperty
  • cApiPropertyCollection
  • cApiRight
  • cApiRightCollection
  • cApiSearchTracking
  • cApiSearchTrackingCollection
  • cApiStat
  • cApiStatCollection
  • cApiSystemProperty
  • cApiSystemPropertyCollection
  • cApiTemplate
  • cApiTemplateCollection
  • cApiTemplateConfiguration
  • cApiTemplateConfigurationCollection
  • cApiType
  • cApiTypeCollection
  • cApiUpload
  • cApiUploadCollection
  • cApiUploadMeta
  • cApiUploadMetaCollection
  • cApiUser
  • cApiUserCollection
  • cApiUserPasswordRequest
  • cApiUserPasswordRequestCollection
  • cApiUserProperty
  • cApiUserPropertyCollection
  • NoteCollection
  • NoteItem
  • TODOCollection
  • TODOItem
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  • Todo
  1: <?php
  2: 
  3: /**
  4:  * This file contains the module collection and item class.
  5:  *
  6:  * @package Core
  7:  * @subpackage GenericDB_Model
  8:  * @author Timo Hummel
  9:  * @copyright four for business AG <www.4fb.de>
 10:  * @license http://www.contenido.org/license/LIZENZ.txt
 11:  * @link http://www.4fb.de
 12:  * @link http://www.contenido.org
 13:  */
 14: 
 15: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
 16: 
 17: /**
 18:  * Module collection
 19:  *
 20:  * @package Core
 21:  * @subpackage GenericDB_Model
 22:  */
 23: class cApiModuleCollection extends ItemCollection {
 24:     /**
 25:      * Constructor to create an instance of this class.
 26:      *
 27:      * @throws cInvalidArgumentException
 28:      */
 29:     public function __construct() {
 30:         global $cfg;
 31:         parent::__construct($cfg['tab']['mod'], 'idmod');
 32:         $this->_setItemClass('cApiModule');
 33:     }
 34: 
 35:     /**
 36:      * Creates a new module item
 37:      *
 38:      * @param string  $name
 39:      * @param int     $idclient     [optional]
 40:      * @param string  $alias        [optional]
 41:      * @param string  $type         [optional]
 42:      * @param string  $error        [optional]
 43:      * @param string  $description  [optional]
 44:      * @param int     $deletable    [optional]
 45:      * @param string  $template     [optional]
 46:      * @param int     $static       [optional]
 47:      * @param string  $package_guid [optional]
 48:      * @param string  $package_data [optional]
 49:      * @param string  $author       [optional]
 50:      * @param string  $created      [optional]
 51:      * @param string  $lastmodified [optional]
 52:      *
 53:      * @return cApiModule
 54:      * @global int    $client
 55:      * @global object $auth
 56:      * @throws cDbException
 57:      * @throws cException
 58:      * @throws cInvalidArgumentException
 59:      */
 60:     public function create($name, $idclient = NULL, $alias = '', $type = '',
 61:             $error = 'none', $description = '', $deletable = 0, $template = '',
 62:             $static = 0, $package_guid = '', $package_data = '', $author = '',
 63:             $created = '', $lastmodified = '') {
 64:         global $client, $auth;
 65: 
 66:         if (NULL === $idclient) {
 67:             $idclient = $client;
 68:         }
 69: 
 70:         if (empty($author)) {
 71:             $author = $auth->auth['uname'];
 72:         }
 73:         if (empty($created)) {
 74:             $created = date('Y-m-d H:i:s');
 75:         }
 76:         if (empty($lastmodified)) {
 77:             $lastmodified = date('Y-m-d H:i:s');
 78:         }
 79: 
 80:         /** @var cApiModule $item */
 81:         $item = $this->createNewItem();
 82: 
 83:         $item->set('idclient', $idclient);
 84:         $item->set('name', $name);
 85:         $item->set('alias', $alias);
 86:         $item->set('type', $type);
 87:         $item->set('error', $error);
 88:         $item->set('description', $description);
 89:         $item->set('deletable', $deletable);
 90:         $item->set('template', $template);
 91:         $item->set('static', $static);
 92:         $item->set('package_guid', $package_guid);
 93:         $item->set('package_data', $package_data);
 94:         $item->set('author', $author);
 95:         $item->set('created', $created);
 96:         $item->set('lastmodified', $lastmodified);
 97:         $item->store();
 98: 
 99:         return $item;
100:     }
101: 
102:     /**
103:      * Returns list of all types by client id
104:      *
105:      * @param int $idclient
106:      *
107:      * @return array
108:      * @throws cDbException
109:      */
110:     public function getAllTypesByIdclient($idclient) {
111:         $types = array();
112: 
113:         $sql = "SELECT type FROM `%s` WHERE idclient = %d GROUP BY type";
114:         $sql = $this->db->prepare($sql, $this->table, $idclient);
115:         $this->db->query($sql);
116:         while ($this->db->nextRecord()) {
117:             $types[] = $this->db->f('type');
118:         }
119: 
120:         return $types;
121:     }
122: 
123:     /**
124:      * Returns a list of all modules used by the given client.
125:      * By default the modules are ordered by name but can be ordered by any
126:      * property.
127:      *
128:      * @param int    $idclient
129:      * @param string $oderBy [optional]
130:      *
131:      * @return array
132:      * @throws cDbException
133:      */
134:     public function getAllByIdclient($idclient, $oderBy = 'name') {
135:         $records = array();
136: 
137:         if (!empty($oderBy)) {
138:             $oderBy = ' ORDER BY ' . $this->db->escape($oderBy);
139:         }
140:         $sql = "SELECT * FROM `%s` WHERE idclient = %d{$oderBy}";
141:         $sql = $this->db->prepare($sql, $this->table, $idclient);
142:         $this->db->query($sql);
143:         while ($this->db->nextRecord()) {
144:             $records[$this->db->f('idmod')] = $this->db->toArray();
145:         }
146: 
147:         return $records;
148:     }
149: 
150:     /**
151:      * Returns a list of all modules used by the given client.
152:      * By default the modules are ordered by name but can be ordered by any
153:      * property.
154:      *
155:      * @param int    $idclient
156:      * @param string $type
157:      * @param string $oderBy [optional]
158:      *
159:      * @return array
160:      * @throws cDbException
161:      */
162:     public function getAllByIdclientAndType($idclient, $type, $oderBy = 'name') {
163:         $records = array();
164: 
165:         if (!empty($oderBy)) {
166:             $oderBy = ' ORDER BY ' . $this->db->escape($oderBy);
167:         }
168:         $sql = "SELECT * FROM `%s` WHERE idclient = %d AND type LIKE '%s' {$oderBy}";
169:         $sql = $this->db->prepare($sql, $this->table, $idclient, '%' . $type . '%');
170: 
171:         $this->db->query($sql);
172:         while ($this->db->nextRecord()) {
173:             $records[$this->db->f('idmod')] = $this->db->toArray();
174:         }
175: 
176:         return $records;
177:     }
178: 
179:     /**
180:      * Checks if any modules are in use and returns the data
181:      *
182:      * @return array
183:      *         Returns all templates for all modules
184:      * @throws cDbException
185:      */
186:     public function getModulesInUse() {
187:         global $cfg;
188: 
189:         $db = cRegistry::getDb();
190: 
191:         $sql = 'SELECT
192:                     c.idmod, c.idtpl, t.name
193:                 FROM
194:                 ' . $cfg['tab']['container'] . ' as c,
195:                 ' . $cfg['tab']['tpl'] . " as t
196:                 WHERE
197:                     t.idtpl = c.idtpl
198:                 GROUP BY c.idmod, c.idtpl, t.name
199:                 ORDER BY t.name";
200:         $db->query($sql);
201: 
202:         $aUsedTemplates = array();
203:         if ($db->numRows() != 0) {
204:             while ($db->nextRecord()) {
205:                 $aUsedTemplates[$db->f('idmod')][$db->f('idtpl')]['tpl_name'] = $db->f('name');
206:                 $aUsedTemplates[$db->f('idmod')][$db->f('idtpl')]['tpl_id'] = (int) $db->f('idtpl');
207:             }
208:         }
209: 
210:         return $aUsedTemplates;
211:     }
212: }
213: 
214: /**
215:  * Module item
216:  *
217:  * @package Core
218:  * @subpackage GenericDB_Model
219:  */
220: class cApiModule extends Item {
221: 
222:     /**
223:      * for finding module translations in source code of module
224:      *
225:      * @var string
226:      */
227:     private $_translationPatternText = '/mi18n([\s]*)\("((\\\\"|[^"])*)"(([\s]*),([\s]*)[^\),]+)*\)/';
228: 
229:     /**
230:      * for finding basic module translations in source code of module
231:      *
232:      * @var string
233:      */
234:     private $_translationPatternBase = '/mi18n([\s]*)\(([\s]*)"/';
235: 
236:     /**
237:      * for replacing base module translations in source code of module
238:      *
239:      * @var string
240:      */
241:     private $_translationReplacement = 'mi18n("';
242: 
243:     /**
244:      * for finding module translations in source code of templates
245:      *
246:      * @var string
247:      */
248:     private $_translationPatternTemplate = '/\{\s*"([^"]+)"\s*\|\s*mi18n\s*\}/';
249: 
250:     /**
251:      * @todo check if this property is still required
252:      * @var string
253:      */
254:     protected $_error;
255: 
256:     /**
257:      * Assoziative package structure array
258:      *
259:      * @var array
260:      */
261:     protected $_packageStructure;
262: 
263:     /**
264:      *
265:      * @var array
266:      */
267:     private $aUsedTemplates = array();
268: 
269:     /**
270:      * Constructor to create an instance of this class.
271:      *
272:      * @param mixed $mId [optional]
273:      *                   Specifies the ID of item to load
274:      * @throws cDbException
275:      * @throws cException
276:      */
277:     public function __construct($mId = false) {
278:         global $cfg, $cfgClient, $client;
279:         parent::__construct($cfg['tab']['mod'], 'idmod');
280: 
281:         // Using no filters is just for compatibility reasons.
282:         // That's why you don't have to stripslashes values if you store them
283:         // using ->set. You have to add slashes, if you store data directly
284:         // (data not from a form field)
285:         $this->setFilters(array(), array());
286: 
287:         if ($mId !== false) {
288:             $this->loadByPrimaryKey($mId);
289:         }
290: 
291:         if (isset($client) && $client != 0) {
292:             $this->_packageStructure = array(
293:                 'jsfiles' => $cfgClient[$client]['js']['path'],
294:                 'tplfiles' => $cfgClient[$client]['tpl']['path'],
295:                 'cssfiles' => $cfgClient[$client]['css']['path']
296:             );
297:         }
298:     }
299: 
300:     /**
301:      * Returns the translated name of the module if a translation exists.
302:      *
303:      * @return string
304:      *         Translated module name or original
305:      * @throws cDbException
306:      * @throws cException
307:      */
308:     public function getTranslatedName() {
309:         global $lang;
310: 
311:         // If we're not loaded, return
312:         if (!$this->isLoaded()) {
313:             return false;
314:         }
315: 
316:         $modname = $this->getProperty('translated-name', $lang);
317: 
318:         if ($modname === false) {
319:             return $this->get('name');
320:         } else {
321:             return $modname;
322:         }
323:     }
324: 
325:     /**
326:      * Sets the translated name of the module
327:      *
328:      * @param string $name
329:      *         Translated name of the module
330:      *
331:      * @throws cDbException
332:      * @throws cException
333:      * @throws cInvalidArgumentException
334:      */
335:     public function setTranslatedName($name) {
336:         global $lang;
337:         $this->setProperty('translated-name', $lang, $name);
338:     }
339: 
340:     /**
341:      * This method get the input and output for translating from files and not
342:      * from db-table.
343:      *
344:      * @param array $cfg
345:      * @param int   $client
346:      * @param int   $lang
347:      *
348:      * @return bool|array
349:      * @throws cException
350:      */
351:     function parseModuleForStringsLoadFromFile($cfg, $client, $lang) {
352:         global $client;
353: 
354:         // If we're not loaded, return
355:         if (!$this->isLoaded()) {
356:             return false;
357:         }
358: 
359:         // Fetch the code, append input to output
360:         $contenidoModuleHandler = new cModuleHandler($this->get('idmod'));
361:         $code = $contenidoModuleHandler->readOutput() . ' ';
362:         $code .= $contenidoModuleHandler->readInput();
363: 
364:         // Initialize array
365:         $strings = array();
366: 
367:         // Split the code into mi18n chunks
368:         $varr = preg_split($this->_translationPatternBase, $code, -1);
369:         array_shift($varr);
370: 
371:         if (count($varr) > 0) {
372:             foreach ($varr as $key => $value) {
373:                 // Search first closing
374:                 $closing = cString::findFirstPos($value, '")');
375: 
376:                 if ($closing === false) {
377:                     $closing = cString::findFirstPos($value, '" )');
378:                 }
379: 
380:                 if ($closing !== false) {
381:                     $value = cString::getPartOfString($value, 0, $closing) . '")';
382:                 }
383: 
384:                 // Append mi18n again
385:                 $varr[$key] = $this->_translationReplacement . $value;
386: 
387:                 // Parse for the mi18n stuff
388:                 preg_match_all($this->_translationPatternText, $varr[$key], $results);
389: 
390:                 // Append to strings array if there are any results
391:                 if (is_array($results[1]) && count($results[2]) > 0) {
392:                     $strings = array_merge($strings, $results[2]);
393:                 }
394: 
395:                 // Unset the results for the next run
396:                 unset($results);
397:             }
398:         }
399: 
400:         //Parse all templates too
401:         $contenidoModulTemplateHandler = new cModuleTemplateHandler($this->get('idmod'), null);
402:         $filesArray = $contenidoModulTemplateHandler->getAllFilesFromDirectory('template');
403: 
404:         if (is_array($filesArray)) {
405:             $code = '';
406:             foreach ($filesArray as $file) {
407:                 $code .= $contenidoModulTemplateHandler->getFilesContent('template', '', $file);
408:             }
409: 
410:             // Parse for the mi18n stuff
411:             preg_match_all($this->_translationPatternTemplate, $code, $results);
412: 
413:             if (is_array($results) && is_array($results[1]) && count($results[1]) > 0) {
414:                 $strings = array_merge($strings, $results[1]);
415:             }
416:         }
417: 
418:         // adding dynamically new module translations by content types
419:         // this function was introduced with CONTENIDO 4.8.13
420:         // checking if array is set to prevent crashing the module translation
421:         // page
422:         if (is_array($cfg['translatable_content_types']) && count($cfg['translatable_content_types']) > 0) {
423:             // iterate over all defines cms content types
424:             foreach ($cfg['translatable_content_types'] as $sContentType) {
425:                 // check if the content type exists and include his class file
426:                 if (file_exists($cfg['path']['contenido'] . 'classes/class.' . cString::toLowerCase($sContentType) . '.php')) {
427:                     cInclude('classes', 'class.' . cString::toLowerCase($sContentType) . '.php');
428:                     // if the class exists, has the method
429:                     // 'addModuleTranslations'
430:                     // and the current module contains this cms content type we
431:                     // add the additional translations for the module
432:                     if (class_exists($sContentType) && method_exists($sContentType, 'addModuleTranslations') && preg_match('/' . cString::toUpperCase($sContentType) . '\[\d+\]/', $code)) {
433: 
434:                         $strings = call_user_func(array(
435:                             $sContentType,
436:                             'addModuleTranslations'
437:                         ), $strings);
438:                     }
439:                 }
440:             }
441:         }
442: 
443:         /* Make the strings unique */
444:         return array_unique($strings);
445:     }
446: 
447:     /**
448:      * Parses the module for mi18n strings and returns them in an array
449:      *
450:      * @return array
451:      *         Found strings for this module
452:      * @throws cInvalidArgumentException
453:      */
454:     public function parseModuleForStrings() {
455:         if (!$this->isLoaded()) {
456:             return false;
457:         }
458: 
459:         // Fetch the code, append input to output
460:         // $code = $this->get('output');
461:         // $code .= $this->get('input');
462:         // Get the code(input,output) from files
463:         $contenidoModuleHandler = new cModuleHandler($this->get('idmod'));
464:         $code = $contenidoModuleHandler->readOutput() . ' ';
465:         $code .= $contenidoModuleHandler->readInput();
466: 
467:         // Initialize array
468:         $strings = array();
469: 
470:         // Split the code into mi18n chunks
471:         $varr = preg_split($this->_translationPatternBase, $code, -1);
472: 
473:         if (count($varr) > 1) {
474:             foreach ($varr as $key => $value) {
475:                 // Search first closing
476:                 $closing = cString::findFirstPos($value, '")');
477: 
478:                 if ($closing === false) {
479:                     $closing = cString::findFirstPos($value, '" )');
480:                 }
481: 
482:                 if ($closing !== false) {
483:                     $value = cString::getPartOfString($value, 0, $closing) . '")';
484:                 }
485: 
486:                 // Append mi18n again
487:                 $varr[$key] = $this->_translationReplacement . $value;
488: 
489:                 // Parse for the mi18n stuff
490:                 preg_match_all($this->_translationPatternText, $varr[$key], $results);
491: 
492:                 // Append to strings array if there are any results
493:                 if (is_array($results[1]) && count($results[2]) > 0) {
494:                     $strings = array_merge($strings, $results[2]);
495:                 }
496: 
497:                 // Unset the results for the next run
498:                 unset($results);
499:             }
500:         }
501: 
502:         global $cfg;
503: 
504:         // adding dynamically new module translations by content types
505:         // this function was introduced with CONTENIDO 4.8.13
506:         // checking if array is set to prevent crashing the module translation
507:         // page
508:         if (is_array($cfg['translatable_content_types']) && count($cfg['translatable_content_types']) > 0) {
509:             // iterate over all defines cms content types
510:             foreach ($cfg['translatable_content_types'] as $sContentType) {
511:                 // check if the content type exists and include his class file
512:                 if (cFileHandler::exists($cfg['path']['contenido'] . 'classes/class.' . cString::toLowerCase($sContentType) . '.php')) {
513:                     cInclude('classes', 'class.' . cString::toLowerCase($sContentType) . '.php');
514:                     // if the class exists, has the method
515:                     // 'addModuleTranslations'
516:                     // and the current module contains this cms content type we
517:                     // add the additional translations for the module
518:                     if (class_exists($sContentType) && method_exists($sContentType, 'addModuleTranslations') && preg_match('/' . cString::toUpperCase($sContentType) . '\[\d+\]/', $code)) {
519: 
520:                         $strings = call_user_func(array(
521:                             $sContentType,
522:                             'addModuleTranslations'
523:                         ), $strings);
524:                     }
525:                 }
526:             }
527:         }
528: 
529:         // Make the strings unique
530:         return array_unique($strings);
531:     }
532: 
533:     /**
534:      * Checks if the module is in use
535:      *
536:      * @param int  $module
537:      * @param bool $bSetData [optional]
538:      * @return bool
539:      *                       true if the module is in use
540:      * @throws cDbException
541:      */
542:     public function moduleInUse($module, $bSetData = false) {
543:         global $cfg;
544: 
545:         $db = cRegistry::getDb();
546: 
547:         $sql = 'SELECT
548:                     c.idmod, c.idtpl, t.name
549:                 FROM
550:                 ' . $cfg['tab']['container'] . ' as c,
551:                 ' . $cfg['tab']['tpl'] . " as t
552:                 WHERE
553:                     c.idmod = '" . cSecurity::toInteger($module) . "' AND
554:                     t.idtpl=c.idtpl
555:                 GROUP BY c.idtpl, c.idmod, t.name
556:                 ORDER BY t.name";
557:         $db->query($sql);
558: 
559:         if ($db->numRows() == 0) {
560:             return false;
561:         } else {
562:             $i = 0;
563:             // save the datas of used templates in array
564:             if ($bSetData === true) {
565:                 while ($db->nextRecord()) {
566:                     $this->aUsedTemplates[$i]['tpl_name'] = $db->f('name');
567:                     $this->aUsedTemplates[$i]['tpl_id'] = (int) $db->f('idmod');
568:                     $i++;
569:                 }
570:             }
571: 
572:             return true;
573:         }
574:     }
575: 
576:     /**
577:      * Get the informations of used templates
578:      *
579:      * @return array
580:      *         template data
581:      */
582:     public function getUsedTemplates() {
583:         return $this->aUsedTemplates;
584:     }
585: 
586:     /**
587:      * Checks if the module is a pre-4.3 module
588:      *
589:      * @return bool
590:      *         true if this module is an old one
591:      */
592:     public function isOldModule() {
593:         // Keywords to scan
594:         $scanKeywords = array(
595:             '$cfgTab',
596:             'idside',
597:             'idsidelang'
598:         );
599: 
600:         $input = $this->get('input');
601:         $output = $this->get('output');
602: 
603:         foreach ($scanKeywords as $keyword) {
604:             if (strstr($input, $keyword)) {
605:                 return true;
606:             }
607:             if (strstr($output, $keyword)) {
608:                 return true;
609:             }
610:         }
611:     }
612: 
613:     /**
614:      * Gets the value of a specific field.
615:      *
616:      * @see Item::getField()
617:      * @param string $field
618:      *         Specifies the field to retrieve
619:      * @param bool $bSafe [optional]
620:      *         Flag to run defined outFilter on passed value
621:      * @return mixed
622:      *         Value of the field
623:      */
624:     public function getField($field, $bSafe = true) {
625:         $value = parent::getField($field, $bSafe);
626: 
627:         switch ($field) {
628:             case 'name':
629:                 if ($value == '') {
630:                     $value = i18n('- Unnamed module -');
631:                 }
632:         }
633: 
634:         return $value;
635:     }
636: 
637:     /**
638:      * Stores the loaded and modified item to the database.
639:      * Also generates the code for all articles using this module
640:      * (if not suppressed by giving a true value for $bJustStore).
641:      *
642:      * @see Item::store()
643:      *
644:      * @param bool $bJustStore [optional]
645:      *                         don't generate code for all articles using this module (default false)
646:      *
647:      * @return bool
648:      */
649:     public function store($bJustStore = false) {
650:         if ($bJustStore) {
651:             // Just store changes, e.g. if specifying the mod package
652:             $success = parent::store();
653:         } else {
654:             cInclude('includes', 'functions.con.php');
655: 
656:             $success = parent::store();
657: 
658:             conGenerateCodeForAllartsUsingMod($this->get('idmod'));
659:         }
660: 
661:         return $success;
662:     }
663: 
664:     /**
665:      * Parse import xml file and returns its values.
666:      *
667:      * @param string $sFile
668:      *         Filename including path of import xml file
669:      * @return array
670:      *         Array with module data from XML file
671:      * @throws cException
672:      */
673:     private function _parseImportFile($sFile) {
674:         $oXmlReader = new cXmlReader();
675:         $oXmlReader->load($sFile);
676: 
677:         $aData = array();
678:         $aInformation = array(
679:             'name',
680:             'description',
681:             'type',
682:             'input',
683:             'output',
684:             'alias'
685:         );
686: 
687:         foreach ($aInformation as $sInfoName) {
688:             $sPath = '/module/' . $sInfoName;
689: 
690:             $value = $oXmlReader->getXpathValue($sPath);
691:             $aData[$sInfoName] = $value;
692:         }
693: 
694:         return $aData;
695:     }
696: 
697:     /**
698:      * Save the modul properties (description,type...)
699:      *
700:      * @param string $sFile Where is the modul info.xml file
701:      *
702:      * @return array
703:      * @throws cException
704:      */
705:     private function _getModuleProperties($sFile) {
706:         $ret = array();
707: 
708:         $aModuleData = $this->_parseImportFile($sFile);
709:         if (count($aModuleData) > 0) {
710:             foreach ($aModuleData as $key => $value) {
711:                 // the columns input/and outputs dont exist in table
712:                 if ($key != 'output' && $key != 'input') {
713:                     $ret[$key] = addslashes($value);
714:                 }
715:             }
716:         }
717: 
718:         return $ret;
719:     }
720: 
721:     /**
722:      * Imports the a module from a zip file, uses xmlparser and callbacks
723:      *
724:      * @param string $sFile
725:      *         Filename of data file (full path)
726:      * @param string $tempName
727:      *         of archive
728:      * @param bool $show_notification [optional]
729:      *         standard: true, mode to turn notifications off
730:      * @return bool
731:      * @throws cDbException
732:      * @throws cException
733:      * @throws cInvalidArgumentException
734:      */
735:     function import($sFile, $tempName, $show_notification = true) {
736:         global $cfgClient, $db, $client, $cfg, $encoding, $lang;
737:         $zip = new ZipArchive();
738:         $notification = new cGuiNotification();
739: 
740:         // file name Hello_World.zip => Hello_World
741:         // @TODO: fetch file extension correctly
742:         $modulName = cString::getPartOfString($sFile, 0, -4);
743: 
744:         $sModulePath = $cfgClient[$client]['module']['path'] . $modulName;
745:         $sTempPath = $cfg['path']['contenido_temp'] . 'module_import_' . $modulName;
746: 
747:         // does module already exist in directory
748:         if (is_dir($sModulePath)) {
749:             if ($show_notification == true) {
750:                 $notification->displayNotification('error', i18n('Module already exists!'));
751:             }
752: 
753:             return false;
754:         }
755: 
756:         if ($zip->open($tempName)) {
757:             if ($zip->extractTo($sTempPath)) {
758:                 $zip->close();
759: 
760:                 // Check module xml information
761:                 if (cFileHandler::exists($sTempPath . '/info.xml')) {
762: 
763:                     // make new module
764:                     $modules = new cApiModuleCollection();
765: 
766:                     $module = $modules->create($modulName);
767:                     $moduleProperties = $this->_getModuleProperties($sTempPath . '/info.xml');
768: 
769:                     // set module properties and save it
770:                     foreach ($moduleProperties as $key => $value) {
771:                         $module->set($key, $value);
772:                     }
773: 
774:                     $module->store();
775:                 } else {
776:                     if ($show_notification == true) {
777:                         $notification->displayNotification('error', i18n('Import failed, could load module information!'));
778:                     }
779:                     return false;
780:                 }
781:             } else {
782:                 if ($show_notification == true) {
783:                     $notification->displayNotification('error', i18n('Import failed, could not extract zip file!'));
784:                 }
785: 
786:                 return false;
787:             }
788:         } else {
789:             if ($show_notification == true) {
790:                 $notification->displayNotification('error', i18n('Could not open the zip file!'));
791:             }
792: 
793:             return false;
794:         }
795: 
796:         // Move into module dir
797:         cDirHandler::rename($sTempPath, $sModulePath);
798: 
799:         return true;
800:     }
801: 
802:     /**
803:      * Imports the a module from a XML file, uses xmlparser and callbacks
804:      *
805:      * @param string $sFile Filename of data file (full path)
806:      *
807:      * @return bool
808:      * @throws cException
809:      * @throws cInvalidArgumentException
810:      */
811:     function importModuleFromXML($sFile) {
812:         global $db, $cfgClient, $client, $cfg, $encoding, $lang;
813: 
814:         $inputOutput = array();
815:         $notification = new cGuiNotification();
816: 
817:         $aModuleData = $this->_parseImportFile($sFile);
818:         if (count($aModuleData) > 0) {
819:             foreach ($aModuleData as $key => $value) {
820:                 if ($this->get($key) != $value) {
821:                     // he columns input/and outputs dont exist in table
822:                     if ($key == 'output' || $key == 'input') {
823:                         $inputOutput[$key] = $value;
824:                     } else {
825:                         $this->set($key, addslashes($value));
826:                     }
827:                 }
828:             }
829: 
830:             $moduleName = cString::cleanURLCharacters($this->get('name'));
831:             $moduleAlias = cString::cleanURLCharacters($this->get('alias'));
832: 
833:             // Is alias empty? Use module name as alias
834:             if ($this->get('alias') == '') {
835:                 $this->set('alias', $moduleName);
836:             }
837: 
838:             if (is_dir($cfgClient[$client]['module']['path'] . $moduleAlias)) {
839:                 $notification->displayNotification('error', i18n('Module exist!'));
840:                 return false;
841:             } else {
842:                 // save it in db table
843:                 $this->store();
844:                 $contenidoModuleHandler = new cModuleHandler($this->get('idmod'));
845:                 if (!$contenidoModuleHandler->createModule($inputOutput['input'], $inputOutput['output'])) {
846:                     $notification->displayNotification('error', i18n('Could not create a module!'));
847:                     return false;
848:                 } else {
849:                     // save the modul data to modul info file
850:                     $contenidoModuleHandler->saveInfoXML();
851:                 }
852:             }
853:         } else {
854:             $notification->displayNotification('error', i18n('Could not parse xml file!'));
855: 
856:             return false;
857:         }
858: 
859:         return true;
860:     }
861: 
862:     /**
863:      * Add recursive folder to zip archive
864:      *
865:      * @param string $dir
866:      *         directory name
867:      * @param string $zipArchive
868:      *         name of the archive
869:      * @param string $zipdir [optional]
870:      */
871:     private function _addFolderToZip($dir, $zipArchive, $zipdir = '') {
872:         if (is_dir($dir)) {
873:             if (false !== $handle = cDirHandler::read($dir)) {
874:                 if (!empty($zipdir)) {
875:                     $zipArchive->addEmptyDir($zipdir);
876:                 }
877: 
878:                 foreach ($handle as $file) {
879:                     // If it's a folder, run the function again!
880:                     if (!is_file($dir . $file)) {
881:                         // Skip parent and root directories
882:                         if (false === cFileHandler::fileNameIsDot($file)) {
883:                             $this->_addFolderToZip($dir . $file . '/', $zipArchive, $zipdir . $file . '/');
884:                         }
885:                     } else {
886:                         // Add the files
887:                         if ($zipArchive->addFile($dir . $file, $zipdir . $file) === false) {
888:                             $notification = new cGuiNotification();
889:                             $notification->displayNotification('error', sprintf(i18n('Could not add file %s to zip!'), $file));
890:                         }
891:                     }
892:                 }
893:             }
894:         }
895:     }
896: 
897:     /**
898:      * Exports the specified module to a zip file
899:      */
900:     public function export() {
901:         $notification = new cGuiNotification();
902:         $moduleHandler = new cModuleHandler($this->get('idmod'));
903: 
904:         // exist modul
905:         if ($moduleHandler->modulePathExists()) {
906:             $zip = new ZipArchive();
907:             $zipName = $this->get('alias') . '.zip';
908:             $cfg = cRegistry::getConfig();
909:             $path = $cfg['path']['contenido_temp'];
910:             if ($zip->open($path . $zipName, ZipArchive::CREATE)) {
911:                 $this->_addFolderToZip($moduleHandler->getModulePath(), $zip);
912: 
913:                 $zip->close();
914:                 // Stream the file to the client
915:                 header('Content-Type: application/zip');
916:                 header('Content-Length: ' . filesize($path . $zipName));
917:                 header("Content-Disposition: attachment; filename=\"$zipName\"");
918:                 readfile($path . $zipName);
919: 
920:                 // erase the file
921:                 unlink($path . $zipName);
922:             } else {
923:                 $notification->displayNotification('error', i18n('Could not open the zip file!'));
924:             }
925:         } else {
926:             $notification->displayNotification('error', i18n("Module don't exist on file system!"));
927:         }
928:     }
929: 
930:     /**
931:      * Userdefined setter for module fields.
932:      *
933:      * @param string $name
934:      * @param mixed $value
935:      * @param bool $bSafe [optional]
936:      *         Flag to run defined inFilter on passed value
937:      *
938:      * @return bool
939:      */
940:     public function setField($name, $value, $bSafe = true) {
941:         switch ($name) {
942:             case 'deletable':
943:             case 'static':
944:                 $value = ($value == 1) ? 1 : 0;
945:                 break;
946:             case 'idclient':
947:                 $value = (int) $value;
948:                 break;
949:         }
950: 
951:         return parent::setField($name, $value, $bSafe);
952:     }
953: 
954:     /**
955:      * Processes container placeholder (e.g. CMS_VAR[123], CMS_VALUE[123]) in given module input code.
956:      * Tries to find the proper container tag and replaces its value against
957:      * container configuration.
958:      * @param int $containerNr
959:      *         The container number to process
960:      * @param string $containerCfg
961:      *         Container configuration string containing key/values pairs for all containers
962:      * @param string $moduleInputCode
963:      * @return string
964:      */
965:     public static function processContainerInputCode($containerNr, $containerCfg, $moduleInputCode) {
966:         $containerConfigurations = array();
967:         if (!empty($containerCfg)) {
968:             $containerConfigurations = cApiContainerConfiguration::parseContainerValue($containerCfg);
969:         }
970: 
971:         $CiCMS_Var = '$C' . $containerNr . 'CMS_VALUE';
972:         $CiCMS_Values = array();
973: 
974:         foreach ($containerConfigurations as $key3 => $value3) {
975:             // Convert special characters and escape backslashes!
976:             $tmp = conHtmlSpecialChars($value3);
977:             $tmp = str_replace('\\', '\\\\', $tmp);
978: 
979:             $CiCMS_Values[] = $CiCMS_Var . '[' . $key3 . '] = "' . $tmp . '";';
980:             $moduleInputCode = str_replace("\$CMS_VALUE[$key3]", $tmp, $moduleInputCode);
981:             $moduleInputCode = str_replace("CMS_VALUE[$key3]", $tmp, $moduleInputCode);
982:         }
983: 
984:         $moduleInputCode = str_replace('CMS_VALUE', $CiCMS_Var, $moduleInputCode);
985:         $moduleInputCode = str_replace("\$" . $CiCMS_Var, $CiCMS_Var, $moduleInputCode);
986:         $moduleInputCode = str_replace('CMS_VAR', 'C' . $containerNr . 'CMS_VAR', $moduleInputCode);
987: 
988:         $CiCMS_Values = implode("\n", $CiCMS_Values);
989: 
990:         return $CiCMS_Values . "\n" . $moduleInputCode;
991:     }
992: }
993: 
CMS CONTENIDO 4.10.0 API documentation generated by ApiGen 2.8.0