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

  • cCodeGeneratorAbstract
  • cCodeGeneratorFactory
  • cCodeGeneratorStandard
  • cContentTypeAbstract
  • cContentTypeAbstractTabbed
  • cContentTypeDate
  • cContentTypeFilelist
  • cContentTypeHead
  • cContentTypeHtml
  • cContentTypeHtmlhead
  • cContentTypeImg
  • cContentTypeImgdescr
  • cContentTypeImgeditor
  • cContentTypeLink
  • cContentTypeLinkdescr
  • cContentTypeLinkeditor
  • cContentTypeLinktarget
  • cContentTypeTeaser
  • cContentTypeText
  • cTypeGenerator
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  • Todo
  1: <?php
  2: /**
  3:  * CONTENIDO code generator abstract class
  4:  *
  5:  * @package    Core
  6:  * @subpackage ContentType
  7:  * @version    SVN Revision $Rev:$
  8:  *
  9:  * @author     Murat Purc <murat@purc.de>
 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:  * CONTENIDO abstract code generator class.
 20:  *
 21:  * @package    Core
 22:  * @subpackage ContentType
 23:  */
 24: 
 25: abstract class cCodeGeneratorAbstract {
 26: 
 27:     /**
 28:      * CONTENIDO database instance
 29:      *
 30:      * @var cDb
 31:      */
 32:     protected $_db;
 33: 
 34:     /**
 35:      * Frontend debug options, see $frontend_debug in __FRONTEND_PATH__/data/config/config.php
 36:      *
 37:      * @var array
 38:      */
 39:     protected $_feDebugOptions = array();
 40: 
 41:     /**
 42:      * Collected CSS data for current template
 43:      *
 44:      * @var string
 45:      */
 46:     protected $_cssData = '';
 47: 
 48:     /**
 49:      * Collected JS data for current template
 50:      *
 51:      * @var string
 52:      */
 53:     protected $_jsData = '';
 54: 
 55:     /**
 56:      * Template name
 57:      *
 58:      * @var string
 59:      */
 60:     protected $_tplName = '';
 61: 
 62:     /**
 63:      * Category id
 64:      *
 65:      * @var int
 66:      */
 67:     protected $_idcat;
 68: 
 69:     /**
 70:      * Article id
 71:      *
 72:      * @var int
 73:      */
 74:     protected $_idart;
 75: 
 76:     /**
 77:      * Language id
 78:      *
 79:      * @var int
 80:      */
 81:     protected $_lang;
 82: 
 83:     /**
 84:      * Client id
 85:      *
 86:      * @var int
 87:      */
 88:     protected $_client;
 89: 
 90:     /**
 91:      * Flag to process layout
 92:      *
 93:      * @var bool
 94:      */
 95:     protected $_layout;
 96: 
 97:     /**
 98:      * Flag to persist generated code
 99:      *
100:      * @var bool
101:      */
102:     protected $_save;
103: 
104:     /**
105:      * Article language id
106:      *
107:      * @var int
108:      */
109:     protected $_idartlang;
110: 
111:     /**
112:      * Page title (generally from article language table)
113:      *
114:      * @var string
115:      */
116:     protected $_pageTitle;
117: 
118:     /**
119:      * Layout code.
120:      * Initially with container tags which will be replaced against module
121:      * outputs.
122:      *
123:      * @var string
124:      */
125:     protected $_layoutCode = '';
126: 
127:     /**
128:      * Module output code prefix
129:      *
130:      * @var array
131:      */
132:     protected $_modulePrefix = array();
133: 
134:     /**
135:      * Module output code
136:      *
137:      * @var string
138:      */
139:     protected $_moduleCode = '';
140: 
141:     /**
142:      * Module output code suffix
143:      *
144:      * @var array
145:      */
146:     protected $_moduleSuffix = array();
147: 
148:     /**
149:      * Module output code suffix
150:      *
151:      * @var array
152:      */
153:     protected $oArtLang;
154: 
155: 
156:     public function __construct() {
157:         $this->_db = cRegistry::getDb();
158:     }
159: 
160:     /**
161:      * Setter for frontend debug options (see $frontend_debug in __FRONTEND_PATH__/data/config/config.php
162:      * located in clients frontend directory)
163:      *
164:      * @param bool $debug
165:      */
166:     public function setFrontendDebugOptions(array $debugOptions) {
167:         $this->_feDebugOptions = $debugOptions;
168:     }
169: 
170:     /**
171:      * Generates the code for a specific article (article for a client in a
172:      * language).
173:      *
174:      * @param int  $idcat
175:      * @param int  $idart
176:      * @param int  $lang
177:      * @param int  $client
178:      * @param bool $layout
179:      * @param bool $save Flag to persist generated code
180:      *
181:      * @throws cInvalidArgumentException if an article with the given idart and idlang can not be loaded
182:      * @return string Generated code or error code '0601' if no template
183:      *         configuration was found for category or article.
184:      */
185:     public function generate($idcat, $idart, $lang, $client, $layout = false, $save = true, $contype = true) {
186:         $this->_idcat = (int)$idcat;
187:         $this->_idart = (int)$idart;
188:         $this->_lang = (int)$lang;
189:         $this->_client = (int)$client;
190:         $this->_layout = (bool)$layout;
191:         $this->_save = (bool)$save;
192: 
193:         $this->oArtLang = new cApiArticleLanguage();
194:         $this->oArtLang->loadByArticleAndLanguageId($idart, $lang);
195:         if (!$this->oArtLang->isLoaded()) {
196:             throw new cInvalidArgumentException('Couldn\'t load article language for idart=' . $idart . 'AND idlang=' . $lang);
197:         }
198: 
199:         $this->_idartlang = $this->oArtLang->get('idartlang');
200:         $this->_pageTitle = stripslashes($this->oArtLang->get('pagetitle'));
201: 
202:         return $this->_generate($contype);
203:     }
204: 
205:     /**
206:      * Generates the code for a specific article (article for a client in a
207:      * language).
208:      *
209:      * @return string The generated code
210:      */
211:     abstract function _generate($contype = true);
212: 
213:     /**
214:      * Returns the template configuration id, either by configured article or by
215:      * configured category.
216:      *
217:      * @return int null
218:      */
219:     protected function _getTemplateConfigurationId() {
220:         // Get configuration for article
221:         $idtplcfg = conGetTemplateConfigurationIdForArticle($this->_idart, $this->_idcat, $this->_lang, $this->_client);
222:         if (is_numeric($idtplcfg) && $idtplcfg != 0) {
223:             // Article is configured
224:             cDebug::out("configuration for article found: $idtplcfg<br><br>");
225:         } else {
226:             // Check whether category is configured
227:             $idtplcfg = conGetTemplateConfigurationIdForCategory($this->_idcat, $this->_lang, $this->_client);
228:             if (NULL !== $idtplcfg) {
229:                 // Category is configured
230:                 cDebug::out("configuration for category found: $idtplcfg<br><br>");
231:             }
232:         }
233: 
234:         return (is_numeric($idtplcfg)) ? $idtplcfg : NULL;
235:     }
236: 
237:     abstract protected function _processNoConfigurationError($idcatart);
238: 
239:     /**
240:      * Returns array containing used layout, template and template name
241:      * @global  array $cfg
242:      * @return  array  Asooziative array like array('idlay' => (int), 'idtpl' => (int), 'name' => (string))
243:      */
244:     protected function _getTemplateData() {
245:         global $cfg;
246: 
247:         // Get IDLAY and IDMOD array
248:         $sql = "SELECT a.idlay AS idlay, a.idtpl AS idtpl, a.name AS name
249:                 FROM `%s` AS a, `%s` AS b WHERE b.idtplcfg = %d AND b.idtpl = a.idtpl;";
250: 
251:         $sql = $this->_db->prepare($sql, $cfg['tab']['tpl'], $cfg['tab']['tpl_conf'], $this->_idtplcfg);
252:         $this->_db->query($sql);
253:         $this->_db->nextRecord();
254:         $data = $this->_db->toArray();
255: 
256:         if ($this->_layout !== false) {
257:             $data['idlay'] = $this->_layout;
258:         }
259: 
260:         $idlay = $data['idlay'];
261:         $idtpl = $data['idtpl'];
262:         cDebug::out("Using Layout: $idlay and Template: $idtpl for generation of code.<br><br>");
263: 
264:         return $data;
265:     }
266: 
267:     /**
268:      * Processes replacements of all existing CMS_...
269:      * tags within passed code
270:      *
271:      * @param array $contentList  Assoziative list of CMS variables
272:      * @param bool  $saveKeywords Flag to save collected keywords during
273:      *                            replacement process.
274:      */
275:     protected function _processCmsTags($contentList, $saveKeywords = true) {
276:         // #####################################################################
277:         // NOTE: Variables below are required in included/evaluated content type
278:         // codes!
279:         global $db, $db2, $sess, $cfg, $code, $cfgClient, $encoding;
280: 
281:         // NOTE: Variables below are additionally required in included/evaluated
282:         // content type codes within backend edit mode!
283:         global $edit, $editLink, $belang;
284: 
285:         $idcat = $this->_idcat;
286:         $idart = $this->_idart;
287:         $lang = $this->_lang;
288:         $client = $this->_client;
289:         $idartlang = $this->_idartlang;
290: 
291:         if (!is_object($db2)) {
292:             $db2 = cRegistry::getDb();
293:         }
294:         // End: Variables required in content type codes
295:         // #####################################################################
296: 
297:         $match = array();
298:         $keycode = array();
299: 
300:         // NOTE: $a_content is used by included/evaluated content type codes below
301:         $a_content = $contentList;
302: 
303:         // Select all cms_type entries
304:         $_typeList = array();
305:         $oTypeColl = new cApiTypeCollection();
306:         $oTypeColl->select();
307:         while ($oType = $oTypeColl->next()) {
308:             $_typeList[] = $oType->toObject();
309:         }
310: 
311:         // Replace all CMS_TAGS[]
312:         foreach ($_typeList as $_typeItem) {
313:             $key = strtolower($_typeItem->type);
314: 
315:             $type = $_typeItem->type;
316:             // Try to find all CMS_{type}[{number}] values, e. g. CMS_HTML[1]
317:             // $tmp = preg_match_all('/(' . $type . ')\[+([a-z0-9_]+)+\]/i',
318:             // $this->_layoutCode, $match);
319:             $tmp = preg_match_all('/(' . $type . '\[+(\d)+\])/i', $this->_layoutCode, $match);
320: 
321:             $a_[$key] = $match[0];
322: 
323:             $success = array_walk($a_[$key], 'extractNumber');
324: 
325:             $search = array();
326:             $replacements = array();
327: 
328:             $typeClassName = $this->_getContentTypeClassName($type);
329:             $typeCodeFile = $this->_getContentTypeCodeFilePathName($type);
330: 
331:             foreach ($a_[$key] as $val) {
332:                 if (class_exists($typeClassName)) {
333:                     // We have a class for the content type, use it
334:                     $tmp = $a_content[$_typeItem->type][$val];
335:                     $cTypeObject = new $typeClassName($tmp, $val, $a_content);
336:                     if (cRegistry::isBackendEditMode()) {
337:                         $tmp = $cTypeObject->generateEditCode();
338:                     } else {
339:                         $tmp = $cTypeObject->generateViewCode();
340:                     }
341:                 } else if (cFileHandler::exists($typeCodeFile)) {
342:                     // Include CMS type code file
343:                     include($typeCodeFile);
344:                 }
345: 
346:                 $search[$val] = sprintf('%s[%s]', $type, $val);
347:                 $replacements[$val] = $tmp;
348:                 $keycode[$type][$val] = $tmp;
349:             }
350: 
351:             $this->_layoutCode = str_ireplace($search, $replacements, $this->_layoutCode);
352:         }
353:     }
354: 
355:     /**
356:      * Processes title tag in page code (layout)
357:      */
358:     abstract protected function _processCodeTitleTag();
359: 
360:     /**
361:      * Processes all meta tags in page code (layout)
362:      */
363:     abstract protected function _processCodeMetaTags();
364: 
365:     /**
366:      * Replaces all container/module configuration tags (CMS_VALUE[n] values)
367:      * against their settings.
368:      *
369:      * @param int    $containerId  Container id
370:      * @param string $containerCfg A string being formatted like concatenated
371:      *                             query
372:      *                             parameter, e. g. param1=value1&param2=value2...
373:      *
374:      * @return string Concatenated PHP code containing CMS_VALUE variables and
375:      *         their values
376:      */
377:     protected function _processCmsValueTags($containerId, $containerCfg) {
378:         $containerCfgList = array();
379: 
380:         $containerCfg = preg_replace('/(&\$)/', '', $containerCfg);
381:         parse_str($containerCfg, $containerCfgList);
382:         /*
383:          * $tmp1 = preg_split('/&/', $containerCfg); foreach ($tmp1 as $key1 =>
384:          * $value1) { $tmp2 = explode('=', $value1); foreach ($tmp2 as $key2 =>
385:          * $value2) { $containerCfgList["$tmp2[0]"] = $tmp2[1]; } }
386:          */
387: 
388:         $CiCMS_Var = '$C' . $containerId . 'CMS_VALUE';
389:         $CiCMS_Values = array();
390: 
391:         foreach ($containerCfgList as $key3 => $value3) {
392:             $tmp = $value3;
393:             $tmp = str_replace("\'", "'", $tmp);
394:             $CiCMS_Values[] = $CiCMS_Var . '[' . $key3 . '] = "' . $tmp . '"; ';
395:             $this->_moduleCode = str_replace("\$CMS_VALUE[$key3]", $tmp, $this->_moduleCode);
396:             $this->_moduleCode = str_replace("CMS_VALUE[$key3]", $tmp, $this->_moduleCode);
397:         }
398: 
399:         $this->_moduleCode = str_replace("CMS_VALUE", $CiCMS_Var, $this->_moduleCode);
400:         $this->_moduleCode = str_replace("\$" . $CiCMS_Var, $CiCMS_Var, $this->_moduleCode);
401:         $this->_moduleCode = preg_replace("/(CMS_VALUE\[)([0-9]*)(\])/i", '', $this->_moduleCode);
402: 
403:         return implode("\n", $CiCMS_Values);
404:     }
405: 
406:     /**
407:      * Extends container code by adding several debug features, if enabled and
408:      * configured.
409:      *
410:      * @param int   $containerId Container id
411:      * @param array $module      Recordset as assoziative array of related module
412:      *        (container code)
413:      */
414:     protected function _processFrontendDebug($containerId, array $module) {
415: 
416:         if (empty($this->_feDebugOptions)) {
417:             return;
418:         }
419: 
420:         $sFeDebug = '';
421:         if ($this->_feDebugOptions['container_display'] == true) {
422:             $sFeDebug .= "Container: CMS_CONTAINER[$containerId]\\n";
423:         }
424:         if ($this->_feDebugOptions['module_display'] == true) {
425:             $sFeDebug .= "Module: " . $module['name'] . "\\n";
426:         }
427: 
428:         if ($this->_feDebugOptions['module_timing_summary'] == true || $this->_feDebugOptions['module_timing'] == true) {
429:             $sFeDebug .= 'Eval-Time: $modTime' . $containerId . "\\n";
430:             $this->_modulePrefix[] = '$modStart' . $containerId . ' = getmicrotime(true);';
431:             $this->_moduleSuffix[] = '$modEnd' . $containerId . ' = getmicrotime(true);';
432:             $this->_moduleSuffix[] = '$modTime' . $containerId . ' = $modEnd' . $containerId . ' - $modStart' . $containerId . ';';
433:         }
434: 
435:         if ($sFeDebug != '') {
436:             $this->_modulePrefix[] = 'echo \'<img onclick="javascript:showmod' . $containerId . '();" src="' . cRegistry::getBackendUrl() . 'images/but_preview.gif"><br>\';';
437:         }
438: 
439:         if ($this->_feDebugOptions['module_timing_summary'] == true) {
440:             $this->_moduleSuffix[] = 'echo \'<script type="text/javascript">function showmod' . $containerId . '(){window.alert(\\\'\'. "' . addslashes($sFeDebug) . '".\'\\\');} </script>\';';
441:             $this->_moduleSuffix[] = '$cModuleTimes["' . $containerId . '"] = $modTime' . $containerId . ';';
442:             $this->_moduleSuffix[] = '$cModuleNames["' . $containerId . '"] = "' . addslashes($module['name']) . '";';
443:         }
444:     }
445: 
446:     /**
447:      * Replaces container tag in layout against the parsed container code
448:      * (module code).
449:      *
450:      * @param int $containerId Container id
451:      */
452:     protected function _processCmsContainer($containerId) {
453:         $cmsContainer = "CMS_CONTAINER[$containerId]";
454: 
455:         // Replace new container (<container id="n"..>) against old one
456:         // (CMS_CONTAINER[n])
457:         $this->_layoutCode = preg_replace("/<container( +)id=\\\"$containerId\\\"(.*)>(.*)<\/container>/Uis", $cmsContainer, $this->_layoutCode);
458:         $this->_layoutCode = preg_replace("/<container( +)id=\\\"$containerId\\\"(.*)\/>/i", $cmsContainer, $this->_layoutCode);
459: 
460:         // Concatenate final container/module output code, but generate PHP code only
461:         // if there is something to generate
462:         $modulePrefix = trim(implode("\n", $this->_modulePrefix));
463:         if (!empty($modulePrefix)) {
464:             $modulePrefix = "<?php\n" . $modulePrefix . "\n?>";
465:         }
466:         $moduleSuffix = trim(implode("\n", $this->_moduleSuffix));
467:         if (!empty($moduleSuffix)) {
468:             $moduleSuffix = "<?php\n" . $moduleSuffix . "\n?>";
469:         }
470:         $moduleOutput = $modulePrefix . $this->_moduleCode . $moduleSuffix;
471: 
472:         // Replace container (CMS_CONTAINER[n]) against the container code
473:         $this->_layoutCode = str_ireplace($cmsContainer, $moduleOutput, $this->_layoutCode);
474:         // $this->_layoutCode = addslashes($this->_layoutCode);
475:     }
476: 
477:     /**
478:      * Returns array of all CMS_...
479:      * vars being used by current article and language
480:      *
481:      * @return array like $arr[type][typeid] = value;
482:      */
483:     protected function _getUsedCmsTypesData() {
484:         global $cfg;
485: 
486:         $return = array();
487: 
488:         // Find out what kind of CMS_... Vars are in use
489:         $sql = "SELECT * FROM `%s` AS A, `%s` AS B, `%s` AS C
490:                 WHERE A.idtype = C.idtype AND A.idartlang = B.idartlang AND B.idart = %d AND B.idlang = %d";
491:         $sql = $this->_db->prepare($sql, $cfg['tab']['content'], $cfg['tab']['art_lang'], $cfg['tab']['type'], $this->_idart, $this->_lang);
492:         $this->_db->query($sql);
493:         while ($this->_db->nextRecord()) {
494:             $return[$this->_db->f('type')][$this->_db->f('typeid')] = $this->_db->f('value');
495:         }
496: 
497:         return $return;
498:     }
499: 
500:     /**
501:      * Resets module related variables
502:      */
503:     protected function _resetModule() {
504:         $this->_modulePrefix = array();
505:         $this->_moduleCode = '';
506:         $this->_moduleSuffix = array();
507:     }
508: 
509:     /**
510:      * Returns the classname for a content type.
511:      *
512:      * @param  string $type  Content type, e. g. CMS_HTMLHEAD
513:      *
514:      * @return  string  The classname e. g. cContentTypeHtmlhead for content type CMS_HTMLHEAD
515:      */
516:     protected function _getContentTypeClassName($type) {
517:         $typeClassName = 'cContentType' . ucfirst(strtolower(str_replace('CMS_', '', $type)));
518: 
519:         return $typeClassName;
520:     }
521: 
522:     /**
523:      * Returns the full path to the include file name of a content type.
524:      *
525:      * @param  string $type  Content type, e. g. CMS_HTMLHEAD
526:      *
527:      * @return  string  The full path e. g. {path_to_contenido_includes}/type/code/include.CMS_HTMLHEAD.code.php
528:      *                  for content type CMS_HTMLHEAD
529:      */
530:     protected function _getContentTypeCodeFilePathName($type) {
531:         global $cfg;
532:         $typeCodeFile = cRegistry::getBackendPath() . $cfg['path']['includes'] . 'type/code/include.' . $type . '.code.php';
533: 
534:         return $typeCodeFile;
535:     }
536: 
537:     /**
538:      * returns the artlang object
539:      */
540:     protected function getArtLangObject() {
541:         return $this->oArtLang;
542:     }
543: }
544: 
CMS CONTENIDO 4.9.0 API documentation generated by ApiGen 2.8.0