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
    • ContentRssCreator
    • ContentSitemapHtml
    • ContentSitemapXml
    • ContentUserForum
    • NavigationTop
    • ScriptCookieDirective
  • 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
  • cContentTypeRaw
  • cContentTypeTeaser
  • cContentTypeText
  • cTypeGenerator
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  • Todo
  1: <?php
  2: 
  3: /**
  4:  * CONTENIDO standard code generator
  5:  *
  6:  * @package Core
  7:  * @subpackage ContentType
  8:  * @author Murat Purc <murat@purc.de>
  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:  * CONTENIDO standard code generator.
 19:  *
 20:  * @package Core
 21:  * @subpackage ContentType
 22:  */
 23: class cCodeGeneratorStandard extends cCodeGeneratorAbstract {
 24: 
 25:     /**
 26:      * Generates the code for a specific article (article for a client in a
 27:      * language).
 28:      *
 29:      * @see cCodeGeneratorAbstract::_generate()
 30:      * @param bool $contype [optional]
 31:      *         Flag to enable/disable replacement of CMS_TAGS[]
 32:      * @param bool $editable [optional]
 33:      * @param int|NULL $version [optional]
 34:      * @return string
 35:      *         The generated code
 36:      */
 37:     public function _generate($contype = true, $editable = true, $version = NULL) {
 38:         global $cfg, $code;
 39: 
 40:         $this->_cssData = '';
 41:         $this->_jsData = '';
 42:         $this->_tplName = '';
 43: 
 44:         cDebug::out("conGenerateCode($this->_idcat, $this->_idart, $this->_lang, $this->_client, $this->_layout);<br>");
 45: 
 46:         // Set category article id
 47:         $idcatart = conGetCategoryArticleId($this->_idcat, $this->_idart);
 48: 
 49:         // Set configuration for article
 50:         $this->_idtplcfg = $this->_getTemplateConfigurationId();
 51:         if (NULL === $this->_idtplcfg) {
 52:             $this->_processNoConfigurationError($idcatart);
 53:             return '0601';
 54:         }
 55: 
 56:         // List of configured container
 57:         $containerConfigurations = conGetContainerConfiguration($this->_idtplcfg);
 58: 
 59:         // Set idlay and idmod array
 60:         $data = $this->_getTemplateData();
 61:         $idlay = $data['idlay'];
 62:         $idtpl = $data['idtpl'];
 63:         $this->_tplName = cString::cleanURLCharacters($data['name']);
 64: 
 65:         // List of used modules
 66:         $containerModules = conGetUsedModules($idtpl);
 67: 
 68:         // Load layout code from file
 69:         $layoutInFile = new cLayoutHandler($idlay, '', $cfg, $this->_lang);
 70:         $this->_layoutCode = $layoutInFile->getLayoutCode();
 71:         $this->_layoutCode = cString::normalizeLineEndings($this->_layoutCode, "\n");
 72: 
 73:         $moduleHandler = new cModuleHandler();
 74: 
 75:         // Create code for all containers
 76:         if ($idlay) {
 77:             cInclude('includes', 'functions.tpl.php');
 78:             $containerNumbers = tplGetContainerNumbersInLayout($idlay);
 79: 
 80:             foreach ($containerNumbers as $containerNr) {
 81:                 if (!isset($containerModules[$containerNr]) || !is_numeric($containerModules[$containerNr])) {
 82:                     // No configured module in this container
 83:                     // reset current module state and process empty container
 84:                     $this->_resetModule();
 85:                     $this->_processCmsContainer($containerNr);
 86:                     continue;
 87:                 }
 88: 
 89:                 $containerModuleId = $containerModules[$containerNr];
 90:                 $oModule = new cApiModule($containerModuleId);
 91:                 $module = $oModule->toArray();
 92:                 if (false === $module) {
 93:                     $module = array();
 94:                 }
 95: 
 96:                 $this->_resetModule();
 97: 
 98:                 $this->_modulePrefix[] = '$cCurrentModule = ' . $containerModuleId . ';';
 99:                 $this->_modulePrefix[] = '$cCurrentContainer = ' . $containerNr . ';';
100: 
101:                 $moduleHandler = new cModuleHandler($containerModuleId);
102:                 $input = '';
103:                 $this->_moduleCode = '';
104: 
105:                 // Get the contents of input and output from files and not from
106:                 // db-table
107:                 if ($moduleHandler->modulePathExists() == true) {
108:                     // do not execute faulty modules
109:                     // caution: if no module is bound to a container then idmod of $oModule is false
110:                     // caution: and as result error field is also empty
111:                     if ($oModule->get('error') === 'none' || $oModule->get('idmod') === false) {
112:                         $this->_moduleCode = $moduleHandler->readOutput();
113:                     } else {
114:                         continue;
115:                     }
116: 
117:                     // Load css and js content of the js/css files
118:                     if ($moduleHandler->getFilesContent('css', 'css') !== false) {
119:                         $this->_cssData .= $moduleHandler->getFilesContent('css', 'css');
120:                     }
121: 
122:                     if ($moduleHandler->getFilesContent('js', 'js') !== false) {
123:                         $this->_jsData .= $moduleHandler->getFilesContent('js', 'js');
124:                     }
125: 
126:                     $input = $moduleHandler->readInput();
127:                 }
128: 
129:                 // strip comments from module code, see CON-1536
130:                 // regex is not enough to correctly remove comments
131:                 // use php_strip_whitespace instead of writing own parser
132:                 // downside: php_strip_whitespace requires a file as parameter
133:                 $tmpFile = dirname(cRegistry::getBackendPath()) . '/' . $cfg['path']['temp'] . uniqid('code_gen_') . '.php';
134:                 if (cFileHandler::exists(dirname($tmpFile))
135:                     && cFileHandler::readable(dirname($tmpFile))
136:                     && cFileHandler::writeable(dirname($tmpFile))) {
137:                     if (false !== cFileHandler::write($tmpFile, $this->_moduleCode)) {
138:                         $this->_moduleCode = php_strip_whitespace($tmpFile);
139:                     }
140:                     // delete file
141:                     cFileHandler::remove($tmpFile);
142:                 }
143: 
144:                 // Process CMS value tags
145:                 $containerCmsValues = $this->_processCmsValueTags($containerNr, $containerConfigurations[$containerNr]);
146: 
147:                 // Add CMS value code to module prefix code
148:                 if ($containerCmsValues) {
149:                     $this->_modulePrefix[] = $containerCmsValues;
150:                 }
151: 
152:                 // Process frontend debug
153:                 $this->_processFrontendDebug($containerNr, $module);
154: 
155:                 // Replace new containers
156:                 $this->_processCmsContainer($containerNr);
157:             }
158:         }
159: 
160:         // Find out what kind of CMS_... Vars are in use
161:         $a_content = $this->_getUsedCmsTypesData($editable, $version);
162: 
163:         // Replace all CMS_TAGS[]
164:         if ($contype) {
165:             $this->_processCmsTags($a_content, true, $editable);
166:         }
167: 
168:         // Add/replace title tag
169:         $this->_processCodeTitleTag();
170: 
171:         // Add/replace meta tags
172:         $this->_processCodeMetaTags();
173: 
174:         // Save the collected css/js data and save it under the template name
175:         // ([templatename].css , [templatename].js in cache dir
176:         $cssFile = '';
177:         if (strlen($this->_cssData) > 0) {
178:             if (($myFileCss = $moduleHandler->saveContentToFile($this->_tplName, 'css', $this->_cssData)) !== false) {
179:                 $oHTML = new cHTML(array(
180:                     'rel' => 'stylesheet',
181:                     'type' => 'text/css',
182:                     'href' => $myFileCss
183:                 ));
184:                 $oHTML->setTag('link');
185:                 $cssFile = $oHTML->render();
186:             }
187:         }
188: 
189:         $jsFile = '';
190:         if (strlen($this->_jsData) > 0) {
191:             if (($myFileJs = $moduleHandler->saveContentToFile($this->_tplName, 'js', $this->_jsData)) !== false) {
192:                 $jsFile = '<script src="' . $myFileJs . '" type="text/javascript"></script>';
193:             }
194:         }
195: 
196:         // add module CSS at {CSS} position, after title or after opening head
197:         // tag
198:         if (strpos($this->_layoutCode, '{CSS}') !== false) {
199:             $this->_layoutCode = cString::iReplaceOnce('{CSS}', $cssFile, $this->_layoutCode);
200:         } else if (!empty($cssFile)) {
201:             if (strpos($this->_layoutCode, '</title>') !== false) {
202:                 $matches = array();
203:                 preg_match_all("#(<head>.*?</title>)(.*?</head>)#si", $this->_layoutCode, $matches);
204:                 $this->_layoutCode = cString::iReplaceOnce($matches[1][0], $matches[1][0] . $cssFile . $matches[1][1], $this->_layoutCode);
205:             } else {
206:                 $this->_layoutCode = cString::iReplaceOnce('<head>', '<head>' . $cssFile, $this->_layoutCode);
207:             }
208:         }
209: 
210:         if (strpos($this->_layoutCode, '{REV}') !== false) {
211:             $this->_layoutCode = cString::iReplaceOnce('{REV}', ((int) getEffectiveSetting("ressource", "revision", 0)), $this->_layoutCode);
212:         }
213: 
214:         // add module JS at {JS} position or before closing body tag if there is
215:         // no {JS}
216:         if (strpos($this->_layoutCode, '{JS}') !== false) {
217:             $this->_layoutCode = cString::iReplaceOnce('{JS}', $jsFile, $this->_layoutCode);
218:         } else if (!empty($jsFile)) {
219:             $this->_layoutCode = cString::iReplaceOnce('</body>', $jsFile . '</body>', $this->_layoutCode);
220:         }
221: 
222:         if (strpos($this->_layoutCode, '{META}') !== false) {
223:             $this->_layoutCode = cString::iReplaceOnce('{META}', $this->_processCodeMetaTags(), $this->_layoutCode);
224:         } else {
225:             $this->_layoutCode = cString::iReplaceOnce('</head>', $this->_processCodeMetaTags() . '</head>', $this->_layoutCode);
226:         }
227: 
228:         if ($this->_feDebugOptions['general_information']) {
229:             $debugPrefix = '';
230: 
231:             $debugPrefix .= "<?php\nif (\$frontend_debug['general_information']) {\n";
232:             $debugPrefix .= "\techo(\"<!-- \\n\\n\");\n";
233: 
234:             $layout = new cApiLayout($idlay);
235:             $layouName = $layout->get('name');
236:             $debugPrefix .= "\techo(\"Layout: " . $layouName . " (" . $idlay . ")\\n\");\n";
237: 
238:             $debugPrefix .= "\techo(\"Template: " . $this->_tplName . " (" . $idtpl . ")\\n\");\n";
239: 
240:             $article = new cApiArticleLanguage($this->_idartlang);
241:             $catart = new cApiCategoryArticle();
242:             $cat = new cApiCategoryLanguage();
243:             $cat->loadByCategoryIdAndLanguageId($this->_idcat, $article->get('idlang'));
244:             $catart->loadByMany(array(
245:                 'idcat' => $cat->get('idcat'),
246:                 'idart' => $article->get('idart')
247:             ));
248:             $lang = new cApiLanguage($article->get('idlang'));
249:             $debugPrefix .= "\techo(\"Language: " . $lang->get('idlang') . " (" . $lang->get('name') . ")\\n\");\n";
250: 
251:             $debugPrefix .= "\techo(\"Category: " . $cat->get('idcat') . " (" . $cat->get('name') . ")\\n\");\n";
252: 
253:             $articleName = $article->get('title');
254:             $debugPrefix .= "\techo(\"Article: " . $articleName . " (catart = " . $catart->get('idcatart') . ", artlang = " . $this->_idartlang . ", art = " . $article->get('idart') . ")\\n\");\n";
255: 
256:             $debugPrefix .= "\techo(\"\\n--> \\n\");\n";
257:             $debugPrefix .= "}\n?>";
258: 
259:             $this->_layoutCode = $debugPrefix . $this->_layoutCode;
260:         }
261: 
262:         // Save the generated code even if there are faulty modules.
263:         // if one does not do so a non existing cache file will be tried to be loaded in frontend
264:         $this->_saveGeneratedCode($idcatart);
265: 
266:         return $this->_layoutCode;
267:     }
268: 
269:     /**
270:      * Will be invoked, if code generation wasn't able to find a configured
271:      * article or category.
272:      * Creates a error message and writes this into the code cache.
273:      *
274:      * @param int $idcatart
275:      *         category article id
276:      */
277:     protected function _processNoConfigurationError($idcatart) {
278:         cDebug::out('Neither CAT or ART are configured!<br><br>');
279: 
280:         $code = '<html><body>No code was created for this article in this category.</body><html>';
281:         $this->_saveGeneratedCode($idcatart, $code, false);
282:     }
283: 
284:     /**
285:      * Processes and adds or replaces title tag for an article.
286:      * Also calls the CEC 'Contenido.Content.CreateTitletag' for user defined
287:      * title creation.
288:      *
289:      * @see cCodeGeneratorAbstract::_processCodeTitleTag()
290:      * @return string
291:      */
292:     protected function _processCodeTitleTag() {
293:         if ($this->_pageTitle == '') {
294:             cApiCecHook::setDefaultReturnValue($this->_pageTitle);
295:             $this->_pageTitle = cApiCecHook::executeAndReturn('Contenido.Content.CreateTitletag');
296:         }
297: 
298:         $headTag = array();
299:         // find head tags in layout code (case insensitive, search across linebreaks)
300:         if (false === preg_match_all('/<head>.*?<\/head>/is', $this->_layoutCode, $headTag)) {
301:             // no head tag
302:             return $this->_layoutCode;
303:         }
304:         if (0 === count($headTag)
305:         || false === isset($headTag[0])
306:         || false === isset($headTag[0][0])) {
307:             // no head tag
308:             return $this->_layoutCode;
309:         }
310:         // use first head tag found (by definition there must always be only 1 tag
311:         // but user supplied markup might be incorrect)
312:         $headTag = $headTag[0][0];
313: 
314:         // Add or replace title
315:         if ($this->_pageTitle != '') {
316:             $replaceTag = '{__TITLE__' . md5(rand().time()) . '}';
317:             $headCode = preg_replace('/<title>.*?<\/title>/is', $replaceTag, $headTag, 1);
318: 
319:             if (false !== strpos($headCode, $replaceTag)) {
320:                 $headCode = str_ireplace($replaceTag, '<title>' . $this->_pageTitle . '</title>', $headCode);
321:             } else {
322:                 $headCode = cString::iReplaceOnce('</head>', '<title>' . $this->_pageTitle . "</title>\n</head>", $headCode);
323:             }
324:         } else {
325:             // remove empty title tags from head tag
326:             $headCode = str_replace('<title></title>', '', $headTag);
327:         }
328:         // overwrite first head tag in original layout code
329:         $this->_layoutCode = preg_replace('/<head>.*?<\/head>/is', $headCode, $this->_layoutCode, 1);
330: 
331:         return $this->_layoutCode;
332:     }
333: 
334:     /**
335:      * Processes and adds or replaces all meta tags for an article.
336:      * Also calls the CEC 'Contenido.Content.CreateMetatags' for user defined
337:      * meta tags creation.
338:      *
339:      * @global array $encoding
340:      * @return string
341:      */
342:     protected function _processCodeMetaTags() {
343:         global $encoding;
344: 
345:         // get basic meta tags (from article & system)
346:         $metaTags = $this->_getBasicMetaTags();
347: 
348:         // process chain Contenido.Content.CreateMetatags to update meta tags
349:         $_cecIterator = cRegistry::getCecRegistry()->getIterator('Contenido.Content.CreateMetatags');
350:         if ($_cecIterator->count() > 0) {
351:             while (false !== $chainEntry = $_cecIterator->next()) {
352:                 $metaTags = $chainEntry->execute($metaTags);
353:             }
354:         }
355: 
356:         $sMetatags = '';
357: 
358:         foreach ($metaTags as $value) {
359: 
360:             // get meta tag keys
361:             $valueKeys = array_keys($value);
362:             $nameKey = 'name';
363:             foreach ($valueKeys as $key) {
364: 
365:                 if ($key != 'content')
366:                     $nameKey = $key;
367:             }
368: 
369:             // decode entities and htmlspecialchars, content will be converted
370:             // later using conHtmlSpecialChars() by render() function
371:             if (isset($value['content'])) {
372:                 $value['content'] = str_replace('"', '\"', (conHtmlEntityDecode(stripslashes($value['content']))));
373:             }
374: 
375:             // build up metatag string
376:             $oMetaTagGen = new cHTML();
377:             $oMetaTagGen->setTag('meta');
378:             $oMetaTagGen->updateAttributes($value);
379: 
380:             // HTML does not allow ID for meta tags
381:             $oMetaTagGen->removeAttribute('id');
382: 
383:             // check if metatag already exists
384:             $sPattern = '/(<meta(?:\s+)' . $nameKey . '(?:\s*)=(?:\s*)(?:\\"|\\\')(?:\s*)' . $value[$nameKey] . '(?:\s*)(?:\\"|\\\')(?:[^>]+)>\n?)/i';
385:             if (preg_match($sPattern, $this->_layoutCode, $aMatch)) {
386:                 // the meta tag is already specified in the layout
387:                 // replace it only if its attributes are not empty
388:                 $replace = true;
389:                 foreach ($value as $test) {
390:                     if ($test == '') {
391:                         $replace = false;
392:                         break;
393:                     }
394:                 }
395:                 if ($replace) {
396:                     $this->_layoutCode = str_replace($aMatch[1], $oMetaTagGen->render() . "\n", $this->_layoutCode);
397:                 }
398:             } else {
399:                 $sMetatags .= $oMetaTagGen->render() . "\n";
400:             }
401:         }
402: 
403:         return $sMetatags;
404:     }
405: 
406:     /**
407:      * Saves the generated code if layout flag is false and save flag is true.
408:      *
409:      * @global array $cfgClient
410:      * @param int $idcatart
411:      *         Category article id
412:      * @param string $code [optional]
413:      *         parameter for setting code manually instead of using the generated layout code
414:      * @param bool $flagCreateCode [optional]
415:      *         whether the create code flag in cat_art should be set or not (optional)
416:      */
417:     protected function _saveGeneratedCode($idcatart, $code = '', $flagCreateCode = true) {
418:         global $cfgClient;
419: 
420:         // Write code in the cache of the client. If the folder does not exist
421:         // create one.
422:         // do not write code cache into root directory of client
423:         if (cRegistry::getFrontendPath() === $cfgClient[$this->_client]['code']['path']) {
424:             return;
425:         }
426: 
427:         // parent directory must be named cache
428:         $directoryName = basename(dirname($cfgClient[$this->_client]['code']['path']));
429:         if ('cache' !== $directoryName) {
430:             // directory name is not cache -> abort
431:             return;
432:         }
433: 
434:         // CON-2113
435:         // Do not overwrite an existing .htaccess file to prevent misconfiguring permissions
436:         if ($this->_layout == false && $this->_save == true && isset($cfgClient[$this->_client]['code']['path'])) {
437:             if (false === is_dir($cfgClient[$this->_client]['code']['path'])) {
438:                 mkdir($cfgClient[$this->_client]['code']['path']);
439:                 @chmod($cfgClient[$this->_client]['code']['path'], 0777);
440:             }
441: 
442:             if (true !== cFileHandler::exists($cfgClient[$this->_client]['code']['path'] . '.htaccess')) {
443:                 cFileHandler::write($cfgClient[$this->_client]['code']['path'] . '.htaccess', "Order Deny,Allow\nDeny from all\n");
444:             }
445: 
446:             if (true === is_dir($cfgClient[$this->_client]['code']['path'])) {
447:                 $fileCode = ($code == '')? $this->_layoutCode : $code;
448: 
449:                 $code = "<?php\ndefined('CON_FRAMEWORK') or die('Illegal call');\n\n?>\n" . $fileCode;
450:                 cFileHandler::write($cfgClient[$this->_client]['code']['path'] . $this->_client . '.' . $this->_lang . '.' . $idcatart . '.php', $code, false);
451: 
452:                 // Update create code flag
453:                 if ($flagCreateCode == true) {
454:                     $oCatArtColl = new cApiCategoryArticleCollection();
455:                     $oCatArtColl->setCreateCodeFlag($idcatart, 0);
456:                 }
457:             }
458:         }
459:     }
460: 
461:     /**
462:      * Collects and return basic meta tags/elements.
463:      *
464:      * @global array $encoding
465:      * @return array
466:      *         List of assozative meta tag values
467:      */
468:     protected function _getBasicMetaTags() {
469: 
470:         // collect all available meta tag entries with non empty values
471:         $metaTags = array();
472:         foreach (conGetAvailableMetaTagTypes() as $key => $value) {
473:             $metaValue = conGetMetaValue($this->_idartlang, $key);
474:             if (0 < strlen($metaValue)) {
475:                 $metaTags[] = array(
476:                     $value['fieldname'] => $value['metatype'],
477:                     'content' => $metaValue
478:                 );
479:             }
480:         }
481: 
482:         // add generator meta tag
483:         // if the version is appended should be configurable
484:         // due to security reasons
485:         $generator = 'CMS CONTENIDO';
486:         $addVersion = true;
487:         if ($addVersion) {
488:             $cfg = cRegistry::getConfig();
489:             $aVersion = explode('.', CON_VERSION);
490:             $generator .= ' ' . $aVersion[0] . '.' . $aVersion[1];
491:         }
492:         $metaTags[] = array(
493:             'name' => 'generator',
494:             'content' => $generator
495:         );
496: 
497:         // add charset or content type meta tag
498:         global $encoding;
499:         if (getEffectiveSetting('generator', 'html5', 'false') == 'true') {
500:             $metaTags[] = array(
501:                 'charset' => $encoding[$this->_lang]
502:             );
503:         } elseif (getEffectiveSetting('generator', 'xhtml', 'false') == 'true') {
504:             $metaTags[] = array(
505:                 'http-equiv' => 'Content-Type',
506:                 'content' => 'application/xhtml+xml; charset=' . $encoding[$this->_lang]
507:             );
508:         } else {
509:             $metaTags[] = array(
510:                 'http-equiv' => 'Content-Type',
511:                 'content' => 'text/html; charset=' . $encoding[$this->_lang]
512:             );
513:         }
514: 
515:         // update (!) index setting of robots meta tag
516:         // the following value will not be changed
517:         // $index = (bool) $this->getArtLangObject()->get('searchable');
518:         // $metaTags = $this->_updateMetaRobots($metaTags, $index, NULL);
519: 
520:         return $metaTags;
521:     }
522: 
523:     /**
524:      * This method allows to set new values for the robots meta element.
525:      * If NULL is given for $index or $follow, existing settings are *not*
526:      * overwritten. If article should be indexed and followed, 'all' will be
527:      * set.
528:      *
529:      * @param array $metaTags
530:      *         array of meta elements to amend
531:      * @param bool|NULL $index
532:      *         if article should be indexed
533:      * @param bool|NULL $follow
534:      *         if links in article should be followed
535:      * @return array
536:      */
537:     protected function _updateMetaRobots(array $metaTags, $index, $follow) {
538: 
539:         // extract robots setting from current meta elements
540:         list($metaTags, $metaRobots) = $this->_extractMetaElement($metaTags, 'name', 'robots');
541: 
542:         if (is_null($metaRobots)) {
543:             // build new meta element if none could be found
544:             $metaRobots = array(
545:                 'name' => 'robots',
546:                 'content' => ''
547:             );
548:         } else {
549:             $content = array_map('trim', explode(',', $metaRobots['content']));
550:             // determine index from extracted element if given value is NULL
551:             if (is_null($index)) {
552:                 $index = (bool) (in_array('all', $content) || in_array('index', $content));
553:                 if (in_array('index', $content) || in_array('all', $content)) {
554:                     $index = true;
555:                 } else if (in_array('noindex', $content)) {
556:                     $index = true;
557:                 } else {
558:                     $index = NULL;
559:                 }
560:             }
561:             // determine follow from extracted element if given value is NULL
562:             if (is_null($follow)) {
563:                 if (in_array('follow', $content) || in_array('all', $content)) {
564:                     $follow = true;
565:                 } else if (in_array('nofollow', $content)) {
566:                     $follow = true;
567:                 } else {
568:                     $follow = NULL;
569:                 }
570:             }
571:         }
572: 
573:         // build and set new content for robots element
574:         $content = array();
575:         if (true === $index && true === $follow) {
576:             $content[] = 'all';
577:         } else {
578:             if (!is_null($index)) {
579:                 $content[] = $index? 'index' : 'noindex';
580:             }
581:             if (!is_null($follow)) {
582:                 $content[] = $follow? 'follow' : 'nofollow';
583:             }
584:         }
585:         $metaRobots['content'] = implode(',', $content);
586: 
587:         // add robots meta element
588:         $metaTags[] = $metaRobots;
589: 
590:         // what do you expect?
591:         return $metaTags;
592:     }
593: 
594:     /**
595:      * Extracts a meta element of type $type (either 'name' or 'http-equiv') and
596:      * name or HTTP header equivalent $nameOrEquiv from the given array of meta
597:      * elements.
598:      * Both, the reduced array of meta elements and the meta element to be
599:      * extracted are returned as an array. If the meta element to be extracted
600:      * could not be found, NULL will be returned in its place.
601:      *
602:      * @param array $metaTags
603:      * @param string $type
604:      *         either 'name' or 'http-equiv'
605:      * @param string $nameOrEquiv
606:      * @return array
607:      */
608:     protected function _extractMetaElement(array $metaTags, $type, $nameOrEquiv) {
609: 
610:         // prepare result structure
611:         $result = array(
612:             array(),
613:             NULL
614:         );
615: 
616:         // loop all given meta elements
617:         foreach ($metaTags as $metaTag) {
618:             if (!is_array($metaTag)) {
619:                 // skip $metaTag if it's no array
620:                 continue;
621:             } else if (!array_key_exists($type, $metaTag)) {
622:                 // add element to reduced array if it's of different type
623:                 array_push($result[0], $metaTag);
624:             } else if ($metaTag[$type] !== $nameOrEquiv) {
625:                 // add element to reduced array if it has different name
626:                 array_push($result[0], $metaTag);
627:             } else {
628:                 // set element as extracted element
629:                 $result[1] = $metaTag;
630:             }
631:         }
632: 
633:         // what do you expect?
634:         return $result;
635:     }
636: 
637: }
638: 
CMS CONTENIDO 4.9.8 API documentation generated by ApiGen 2.8.0