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
  • Smarty
    • Cacher
    • Compiler
    • Config
    • Debug
    • PluginsBlock
    • PluginsFilter
    • PluginsFunction
    • PluginsInternal
    • PluginsModifier
    • PluginsModifierCompiler
    • PluginsShared
    • Security
    • Template
    • TemplateResources
  • Swift
    • ByteStream
    • CharacterStream
    • Encoder
    • Events
    • KeyCache
    • Mailer
    • Mime
    • Plugins
    • Transport

Classes

  • Swift_FailoverTransport
  • Swift_LoadBalancedTransport
  • Swift_MailTransport
  • Swift_Plugins_Loggers_ArrayLogger
  • Swift_Plugins_Loggers_EchoLogger
  • Swift_SendmailTransport
  • Swift_SmtpTransport
  • Swift_Transport_AbstractSmtpTransport
  • Swift_Transport_Esmtp_Auth_CramMd5Authenticator
  • Swift_Transport_Esmtp_Auth_LoginAuthenticator
  • Swift_Transport_Esmtp_Auth_PlainAuthenticator
  • Swift_Transport_Esmtp_AuthHandler
  • Swift_Transport_EsmtpTransport
  • Swift_Transport_FailoverTransport
  • Swift_Transport_LoadBalancedTransport
  • Swift_Transport_MailTransport
  • Swift_Transport_SendmailTransport
  • Swift_Transport_SimpleMailInvoker
  • Swift_Transport_StreamBuffer

Interfaces

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