* @license http://www.contenido.org/license/LIZENZ.txt * @link http://www.4fb.de * @link http://www.contenido.org * @since file available since contenido release 4.8.12 * * {@internal * created 2009-04-08 * modified 2009-04-14 - added possibility to expand template select by client or system setting using type 'cms_teaser' * modofied 2009-04-21 - added seperate handling for xhtml * modified 2009-05-04 - added sort order sequence * modified 2009-10-01 - Dominik Ziegler, fixed session bug in link * modified 2009-10-12 - Dominik Ziegler, fixed online/offline articles, dynamic teaser generation and translation implemented * modified 2009-10-16 - Dominik Ziegler, added manual date support * modified 2010-01-21 - Dominik Ziegler, strip tags from manual teaser date * * $Id$: * }} * */ if (!defined('CON_FRAMEWORK')) { die('Illegal call'); } cInclude('includes', 'functions.con.php'); cInclude('includes', 'functions.api.images.php'); /** * Class handles content type teaser, its editmode and viewmode. All properties of teaser content type * were stored as xml document in database as content in {prefix}_content * */ class Cms_Teaser { /** * Contenido configuration array * * @var array * @access private */ private $aCfg; /** * Current id of content type CMS_TEASER[3] -> 3 * * @var integer * @access private */ private $iId; /** * Contenido database object * * @var object * @access private */ private $oDb; /** * Idartlang of article, which is currently in edit- or viewmode * * @var integer * @access private */ private $iIdArtLang; /** * List of fieldnames in frontend (properties) which the teaser has * and which were also described in the config xml document * * @var array * @access private */ private $aTeaserData; /** * String contains value of stored content in database * in this case this is the config xml document which is * later parsed and its settings were stored in $aSettings * * @var string * @access private */ private $sContent; /** * Array which contains current teaser settings * * @var array * @access private */ private $aSettings; /** * Array which contains all avariable CMS_Types and its ids * in current Contenido isntallation (described as hash [idtype => cmstypename]) * * @var array * @access private */ private $aCMSTypes; /** * current Contenido client id * * @var integer * @access private */ private $iClient; /** * current Contenido language id * * @var integer * @access private */ private $iLang; /** * Contenido Session object * * @var object * @access private */ private $oSess; /** * Contenido configuration array for currently active client * * @var array * @access private */ private $aCfgClient; /** * print XHTML * * @var string * @access private */ private $sUseXHTML; /** * Placeholders for labels in frontend. * Important: This must be a static array! * @var array * @access private */ private static $aTranslations = array("MORE" => "mehr"); /** * Constructor of class inits some important class variables and * gets some Contenido global vars, so this class has no need to * use ugly and buggy global commands * * @param string $sContent - xml document from database containing teaser settings * @param integer $iNumberOfCms - CMS_TEASER[4] => 4 * @param integer $iIdArtLang - Idartlang of current article * @param array $sEditLink - sEditlink for editbuttons, not currently used * @param array $aCfg - Contenido configuration array * @param array $oDB - Contenido database object (not used because we need own object (else problems by cross query in same object)) * @param string $sContenidoLang - Contenido Backend language string * @param integer $iClient - Contenido client id * @param integer $iLang - Contenido frontend language id * @param array $aCfgClient - Contenido Client configuration array * * @access public */ function __construct($sContent, $iNumberOfCms, $iIdArtLang, $sEditLink, $aCfg, $oDB, $sContenidoLang, $iClient, $iLang, $aCfgClient, $oSess) { //set arguments to class variables directly $this->aCfg = $aCfg; $this->iId = $iNumberOfCms; $this->iIdArtLang = $iIdArtLang; $this->sContent = urldecode($sContent); $this->iClient = $iClient; $this->iLang = $iLang; $this->aCfgClient = $aCfgClient; $this->oSess = $oSess; if (!array_key_exists("generate_xhtml", $aCfg)) { $this->sUseXHTML = getEffectiveSetting("generator", "xhtml", 'false'); } else { $this->sUseXHTML = $aCfg['generate_xhtml']; } //init other variables with default values $this->aCMSTypes = null; $this->aSettings = array(); $this->oDb = new DB_ConLite(); //define class array which contains all names of teaser properties. They were also base for generating dynamic javascripts for //retrival this properties out of html forms and retriving their values to screen $this->aTeaserData = array('teaser_title', 'teaser_category', 'teaser_count', 'teaser_style', 'teaser_manual', 'teaser_start', 'teaser_source_head', 'teaser_source_head_count', 'teaser_source_text', 'teaser_source_text_count', 'teaser_source_image', 'teaser_source_image_count', 'teaser_filter', 'teaser_sort', 'teaser_sort_order', 'teaser_character_limit', 'teaser_image_width', 'teaser_image_height', 'teaser_manual_art', 'teaser_image_crop', 'teaser_source_date', 'teaser_source_date_count'); //if form is submitted there is a need to store current teaser settings //notice: there is also a need, that teaser_id is the same (case: more than ohne cms teaser is used on the same page if (isset($_POST['teaser_action']) && $_POST['teaser_action'] == 'store' && isset($_POST['teaser_id']) && (int) $_POST['teaser_id'] == $this->iId) { $this->storeTeaser(); } //in sContent XML Document is stored, which contains teaser settings, call function which parses this document and store //properties as easy accessible array into $aSettings if (trim($this->sContent) != '') { $this->readSettings(); } $this->setDefaultValues(); } /** * Returns all translation strings for mi18n. * * @param array $aTranslationStrings Array with translation strings * @return array Translation strings */ static public function addModuleTranslations($aTranslationStrings) { foreach (self::$aTranslations as $sValue) { $aTranslationStrings[] = $sValue; } return $aTranslationStrings; } /** * Functen parses XML Document which contains teaser settings * and store properties as array into $aSettings * * @access private */ private function readSettings() { //use XMLReader for parsing XML document $oXmlReader = new XMLReader(); $oXmlReader->XML($this->sContent); //store nodename in order to retrive property name when content of node is read $sLastNode = ''; //in xml document there is a block in this artids for manual teaser were stored //if we were in this block store all values to an art array //this variable defines if we were in this block or not $bPutInArtArray = false; //array for previous described manual art array $this->aSettings['teaser_manual_art'] = array(); while ($oXmlReader->read()) { switch ($oXmlReader->nodeType) { //read property name (ignore root node or block of manual arts for teaser) case XMLReader::ELEMENT: if ($oXmlReader->name != 'teaser' && $oXmlReader->name != 'manual_art' && $oXmlReader->name != 'art') { $sLastNode = 'teaser_' . $oXmlReader->name; $this->aSettings[$sLastNode] = ''; } //if we reach node store all subnotes to artnode array if ($oXmlReader->name == 'art') { $bPutInArtArray = true; } break; //in case of a textnode we have previous propertyname and corrsponding value -> store into aSettings //if we were in mode store to corresponding array case XMLReader::TEXT: if ($bPutInArtArray == true) { $bPutInArtArray = false; array_push($this->aSettings['teaser_manual_art'], Contenido_Security::unfilter($oXmlReader->value)); } else { $this->aSettings[$sLastNode] = Contenido_Security::unfilter($oXmlReader->value); } break; } } } /** * Function gets all submitted values for new teaser properties from * $_POST array, generates new corresponding config XML Document and * stores it as content, using contenido conSaveContentEntry() function * * @access private */ private function storeTeaser() { //create new xml document, its encoding and root node $oXmlDom = new DOMDocument('1.0', 'iso-8859-1'); $oXmlDom->formatOutput = true; $oRootNode = $oXmlDom->createElement('teaser'); $oXmlDom->appendChild($oRootNode); //$this->aTeaserData defines all teaser properties, so try to read them from %_POST foreach ($this->aTeaserData as $sParam) { //in case of article list for manual teaser do a special behaviour if ($sParam == 'teaser_manual_art') { $oParam = $oXmlDom->createElement(str_replace('teaser_', '', $sParam)); //split all arts to array $aArts = explode(';', Contenido_Security::toString($_POST[$sParam])); //for each artid generate subnote in xml document and store its value foreach ($aArts as $iArt) { $iArt = (int) $iArt; if ($iArt > 0) { $oArt = $oXmlDom->createElement('art', $iArt); $oParam->appendChild($oArt); } } } else { //generate xml node for current property and store its value $oParam = $oXmlDom->createElement(str_replace('teaser_', '', $sParam), Contenido_Security::filter($_POST[$sParam], $this->oDb)); } $oXmlDom->firstChild->appendChild($oParam); } //serialize xml document and store new version in class variable and database conSaveContentEntry($this->iIdArtLang, 'CMS_TEASER', $this->iId, $oXmlDom->saveXML(), true); $this->sContent = $oXmlDom->saveXML(); } /** * Function which generated a select box for setting number of articles which were * displayed in teaser as a maximum. Only important in editmode * * @param string $sSelected - value of select box which is selected * @return html string of select box * * @access private */ private function getCountSelect($sSelected) { $this->oDb = new DB_ConLite(); $oHtmlSelect = new cHTMLSelectElement('teaser_count', "", 'teaser_count'); //set please chose option element $oHtmlSelectOption = new cHTMLOptionElement(i18n("Please choose"), '', true); $oHtmlSelect->addOptionElement(0, $oHtmlSelectOption); //generate a select box containing count 1 to 20 for maximum teaser count for ($i = 1; $i <= 20; $i++) { $oHtmlSelectOption = new cHTMLOptionElement($i, $i, false); $oHtmlSelect->addOptionElement($i, $oHtmlSelectOption); } //set default value $oHtmlSelect->setDefault($sSelected); return $oHtmlSelect->render(); } /** * Function which generated a select box for setting teaser style * currently two seperate teaser templates were supported * * @param string $sSelected - value of select box which is selected * @return html string of select box * * @access private */ private function getStyleSelect($sSelected) { $oHtmlSelect = new cHTMLSelectElement('teaser_style', "", 'teaser_style'); //set please chose option element $oHtmlSelectOption = new cHTMLOptionElement(i18n("Please choose"), '', true); $oHtmlSelect->addOptionElement(0, $oHtmlSelectOption); //set other avariable options manually $oHtmlSelectOption = new cHTMLOptionElement(i18n("Block Style"), 'cms_teaser_style_block.html', false); $oHtmlSelect->addOptionElement(1, $oHtmlSelectOption); $oHtmlSelectOption = new cHTMLOptionElement(i18n("Blog Style"), 'cms_teaser_style_blog.html', false); $oHtmlSelect->addOptionElement(2, $oHtmlSelectOption); $aAdditionalOptions = getEffectiveSettingsByType('cms_teaser'); $i = 3; foreach ($aAdditionalOptions as $sLabel => $sTemplate) { $oHtmlSelectOption = new cHTMLOptionElement($sLabel, $sTemplate, false); $oHtmlSelect->addOptionElement($i, $oHtmlSelectOption); $i++; } //set default value $oHtmlSelect->setDefault($sSelected); return $oHtmlSelect->render(); } /** * Function which generated a select box for setting teaser * sort order argument * * @param string $sSelected - value of select box which is selected * @return html string of select box * * @access private */ private function getSortOrderSelect($sSelected) { $oHtmlSelect = new cHTMLSelectElement('teaser_sort_order', "", 'teaser_sort_order'); //set please chose option element $oHtmlSelectOption = new cHTMLOptionElement(i18n("Please choose"), '', true); $oHtmlSelect->addOptionElement(0, $oHtmlSelectOption); //set other avariable options manually $oHtmlSelectOption = new cHTMLOptionElement(i18n("Ascending"), 'asc', false); $oHtmlSelect->addOptionElement(1, $oHtmlSelectOption); $oHtmlSelectOption = new cHTMLOptionElement(i18n("Descending"), 'desc', false); $oHtmlSelect->addOptionElement(2, $oHtmlSelectOption); //set default value $oHtmlSelect->setDefault($sSelected); return $oHtmlSelect->render(); } /** * Function which provides select option for cropping teaser images * * @param string $sSelected - value of select box which is selected * @return html string of select box * * @access private */ private function getCropSelect($sSelected) { $oHtmlSelect = new cHTMLSelectElement('teaser_image_crop', "", 'teaser_image_crop'); //set please chose option element $oHtmlSelectOption = new cHTMLOptionElement(i18n("Please choose"), '', true); $oHtmlSelect->addOptionElement(0, $oHtmlSelectOption); //set other avariable options manually $oHtmlSelectOption = new cHTMLOptionElement(i18n("Scaled"), 'false', false); $oHtmlSelect->addOptionElement(1, $oHtmlSelectOption); $oHtmlSelectOption = new cHTMLOptionElement(i18n("Cropped"), 'true', false); $oHtmlSelect->addOptionElement(2, $oHtmlSelectOption); //set default value $oHtmlSelect->setDefault($sSelected); return $oHtmlSelect->render(); } /** * Function which generated a select box for setting teaser * sort argument * * @param string $sSelected - value of select box which is selected * @return html string of select box * * @access private */ private function getSortSelect($sSelected) { $oHtmlSelect = new cHTMLSelectElement('teaser_sort', "", 'teaser_sort'); //set please chose option element $oHtmlSelectOption = new cHTMLOptionElement(i18n("Please choose"), '', true); $oHtmlSelect->addOptionElement(0, $oHtmlSelectOption); //set other avariable options manually $oHtmlSelectOption = new cHTMLOptionElement(i18n("Sort Sequence"), 'sortsequence', false); $oHtmlSelect->addOptionElement(1, $oHtmlSelectOption); $oHtmlSelectOption = new cHTMLOptionElement(i18n("Creationdate"), 'creationdate', false); $oHtmlSelect->addOptionElement(2, $oHtmlSelectOption); $oHtmlSelectOption = new cHTMLOptionElement(i18n("Publisheddate"), 'publisheddate', false); $oHtmlSelect->addOptionElement(3, $oHtmlSelectOption); $oHtmlSelectOption = new cHTMLOptionElement(i18n("Modificationdate"), 'modificationdate', false); $oHtmlSelect->addOptionElement(4, $oHtmlSelectOption); //set default value $oHtmlSelect->setDefault($sSelected); return $oHtmlSelect->render(); } /** * Function which gets all currenty avariable content types and their ids * from database and store it into class variable aCMSTypes. Because this * information is used multiple, this way causes a better performance to get * this information seperately * * @access private */ private function initCmsTypes() { $this->aCMSTypes = array(); $sSql = 'SELECT * from %s ORDER BY type'; $this->oDb->query(sprintf($sSql, $this->aCfg['tab']['type'])); while ($this->oDb->next_record()) { $this->aCMSTypes[$this->oDb->f('idtype')] = $this->oDb->f('type'); } } /** * Teaser gets informations from other articles and their content typs * Function builds a select box in which coresponding cms type can be selected * after that a text box is rendered for setting id for this conent type to get * informations from. This function is used three times for source defintion of * headline text and teaserimage * * @param unknown_type $sSelectName - name of input elements * @param string $sSelected - value of select box which is selected * @param string $sValue - current value of text box * @return html string of select box * * @access private */ private function getTypeSelect($sSelectName, $sSelected, $sValue) { //generate textbox for content type id $oHtmlInput = new cHTMLTextbox($sSelectName . '_count', $sValue, "", "", $sSelectName . '_count'); //generate content type select $oHtmlSelect = new cHTMLSelectElement($sSelectName, "", $sSelectName); $oHtmlSelectOption = new cHTMLOptionElement(i18n("Please choose"), '', true); $oHtmlSelect->addOptionElement(0, $oHtmlSelectOption); //use $this->aCMSTypes as basis for this select box which contains all avariable content types in system foreach ($this->aCMSTypes as $sKey => $sValue) { $oHtmlSelectOption = new cHTMLOptionElement($sValue, $sValue, false); $oHtmlSelect->addOptionElement($sKey, $oHtmlSelectOption); } $oHtmlSelect->setStyle("width:147px;"); //set default value $oHtmlSelect->setDefault($sSelected); $oHtmlInput->setStyle("width:50px;"); return $oHtmlSelect->render() . $oHtmlInput->render(); } /** * Function is called in editmode of contenido an returns teaser view and editbutton * * @return string - escaped html code for further use in contenido and sending to browser * * @access public */ public function getAllWidgetEdit() { $this->initCmsTypes(); $oTpl = new Template(); /* Set some values into javascript for a better handling */ $oTpl->set('s', 'CON_PATH', $this->aCfg['path']['contenido_fullhtml']); $oTpl->set('s', 'ID', $this->iId); $oTpl->set('s', 'IDARTLANG', $this->iIdArtLang); $oTpl->set('s', 'CONTENIDO', $_REQUEST['contenido']); //output fields for use in javascript $oTpl->set('s', 'FIELDS', "'" . implode("','", $this->aTeaserData) . "'"); /* Start set a lot of translations */ $oTpl->set('s', 'LABEL_TEASERSETTINGS', i18n("Teasersettings")); $oTpl->set('s', 'LABEL_TEASERTITLE', i18n("Teasertitle")); $oTpl->set('s', 'LABEL_START', i18n("Teaser Startarticle")); $oTpl->set('s', 'LABEL_TARGET', i18n("Sourcecategory")); $oTpl->set('s', 'LABEL_COUNT', i18n("Number of Articles")); $oTpl->set('s', 'LABEL_GENERAL', i18n("General Settings")); $oTpl->set('s', 'LABEL_STYLE', i18n("Teaser Style")); $oTpl->set('s', 'LABEL_ADVANCED', i18n("Advanced Teaser Settings")); $oTpl->set('s', 'LABEL_FILTER', i18n("Teaser Filter")); $oTpl->set('s', 'LABEL_SORT', i18n("Teaser Sort")); $oTpl->set('s', 'LABEL_SORT_ORDER', i18n("Sort order")); $oTpl->set('s', 'LABEL_SOURCEHEAD', i18n("Source Headline")); $oTpl->set('s', 'LABEL_SOURCE', i18n("Source Settings")); $oTpl->set('s', 'LABEL_SOURCETEXT', i18n("Source Text")); $oTpl->set('s', 'LABEL_SOURCEIMAGE', i18n("Source Image")); $oTpl->set('s', 'LABEL_SOURCEDATE', i18n("Source Date")); $oTpl->set('s', 'LABEL_CAT', i18n("Category")); $oTpl->set('s', 'LABEL_ART', i18n("Article")); $oTpl->set('s', 'GENERAL', i18n("General")); $oTpl->set('s', 'ADVANCED', i18n("Advanced")); $oTpl->set('s', 'MANUAL', i18n("Manual")); $oTpl->set('s', 'LABEL_EXISTING_ARTICLES', i18n("Included Articles")); $oTpl->set('s', 'LABEL_ADD_ARTICLE', i18n("Add Article")); $oTpl->set('s', 'LABEL_MANUAL', i18n("Manual Teaser Settings")); $oTpl->set('s', 'LABEL_USE_MANUAL', i18n("Manual Teaser")); $oTpl->set('s', 'SIZE_SETTINGS', i18n("Size Settings")); $oTpl->set('s', 'LABEL_CHARACTER_LIMIT', i18n("Characterlength")); $oTpl->set('s', 'LABEL_IMAGE_WIDTH', i18n("Imagewidth")); $oTpl->set('s', 'LABEL_IMAGE_HEIGHT', i18n("Imageheight")); $oTpl->set('s', 'LABEL_IMAGE_CROP', i18n("Image Scale")); /* End set a lot of translations */ /* Start set values into configuration array and generate select boxes used previous defined values CASE CHECKBOXES */ if ($this->aSettings['teaser_start'] == 'true') { $oTpl->set('s', 'START_CHECKED', 'checked'); } else { $oTpl->set('s', 'START_CHECKED', ''); } if ($this->aSettings['teaser_manual'] == 'true') { $oTpl->set('s', 'MANUAL_CHECKED', 'checked'); } else { $oTpl->set('s', 'MANUAL_CHECKED', ''); } /* Start set values into configuration array and generate select boxes used previous defined values CASE CHECKBOXES */ /* Start set values into configuration array and generate select boxes used previous defined values */ $sCatSelect = buildCategorySelect('teaser_category', $this->aSettings['teaser_category'], 0); $oTpl->set('s', 'TARGET_SELECT', $sCatSelect); $oTpl->set('s', 'CAT_SELECT', buildCategorySelect('teaser_cat', 0, 0)); $oTpl->set('s', 'ART_SELECT', buildArticleSelect('teaser_art', 0, 0)); $oTpl->set('s', 'COUNT_SELECT', $this->getCountSelect($this->aSettings['teaser_count'])); $oTpl->set('s', 'STYLE_SELECT', $this->getStyleSelect($this->aSettings['teaser_style'])); $oTpl->set('s', 'SOURCEHEAD_SELECT', $this->getTypeSelect('teaser_source_head', $this->aSettings['teaser_source_head'], $this->aSettings['teaser_source_head_count'])); $oTpl->set('s', 'SOURCETEXT_SELECT', $this->getTypeSelect('teaser_source_text', $this->aSettings['teaser_source_text'], $this->aSettings['teaser_source_text_count'])); $oTpl->set('s', 'SOURCEIAMGE_SELECT', $this->getTypeSelect('teaser_source_image', $this->aSettings['teaser_source_image'], $this->aSettings['teaser_source_image_count'])); $oTpl->set('s', 'SOURCEDATE_SELECT', $this->getTypeSelect('teaser_source_date', $this->aSettings['teaser_source_date'], $this->aSettings['teaser_source_date_count'])); $oTpl->set('s', 'TEASER_TITLE', $this->aSettings['teaser_title']); $oTpl->set('s', 'FILTER_VALUE', $this->aSettings['teaser_filter']); $oTpl->set('s', 'SORT_SELECT', $this->getSortSelect($this->aSettings['teaser_sort'])); $oTpl->set('s', 'SORT_ORDER_SELECT', $this->getSortOrderSelect($this->aSettings['teaser_sort_order'])); $oTpl->set('s', 'IMAGE_CROP_SELECT', $this->getCropSelect($this->aSettings['teaser_image_crop'])); $oTpl->set('s', 'CHARACTER_LIMIT', $this->aSettings['teaser_character_limit']); $oTpl->set('s', 'IMAGE_WIDTH', $this->aSettings['teaser_image_width']); $oTpl->set('s', 'IMAGE_HEIGHT', $this->aSettings['teaser_image_height']); $oTpl->set('s', 'LABEL_ADD', i18n('Add')); $sOptions = ''; if (is_array($this->aSettings['teaser_manual_art'])) { foreach ($this->aSettings['teaser_manual_art'] as $iIdArt) { $sOptions .= '' . "\n"; } } $oTpl->set('s', 'MANUAL_OPTIONS', $sOptions); /* End set values into configuration array and generate select boxes used previous defined values */ $sCode = $oTpl->generate($this->aCfg['path']['contenido'] . 'templates/standard/template.cms_teaser_edit.html', 1); //return $this->encodeForOutput($sCode); return $this->getAllWidgetView(true) . $this->encodeForOutput($sCode); } /** * In Contenido content type code is evaled by php. To make this possible, * this function prepares code for evaluation * * @param string $sCode - code to escape * @return string - escaped code * * @access private */ private function encodeForOutput($sCode) { $sCode = (string) $sCode; $sCode = AddSlashes(AddSlashes($sCode)); $sCode = str_replace("\\\'", "'", $sCode); $sCode = str_replace("\$", '\\\$', $sCode); return $sCode; } /** * Function sets some default values for teaser in case that there is no * value definied * * @access private */ private function setDefaultValues() { //character limit is 120 by default if ((int) $this->aSettings['teaser_character_limit'] == 0) { $this->aSettings['teaser_character_limit'] = 120; } //teaser cont is 6 by default if ((int) $this->aSettings['teaser_count'] == 0) { $this->aSettings['teaser_count'] = 6; } //teasersort is creationdate by default if (strlen($this->aSettings['teaser_sort']) == 0) { $this->aSettings['teaser_sort'] = 'creationdate'; } //teaser style is liststyle by default if (strlen($this->aSettings['teaser_style']) == 0) { $this->aSettings['teaser_style'] = 'cms_teaser_style_blog.html'; } //teaser image width default if ((int) $this->aSettings['teaser_image_width'] == 0) { $this->aSettings['teaser_image_width'] = 100; } //teaser image height default if ((int) $this->aSettings['teaser_image_height'] == 0) { $this->aSettings['teaser_image_height'] = 75; } //cms type head default if (strlen($this->aSettings['teaser_source_head']) == 0) { $this->aSettings['teaser_source_head'] = 'CMS_HTMLHEAD'; } //cms type text default if (strlen($this->aSettings['teaser_source_text']) == 0) { $this->aSettings['teaser_source_text'] = 'CMS_HTML'; } //cms type image default if (strlen($this->aSettings['teaser_source_image']) == 0) { $this->aSettings['teaser_source_image'] = 'CMS_IMG'; } //cms type date default if (strlen($this->aSettings['teaser_source_date']) == 0) { $this->aSettings['teaser_source_date'] = 'CMS_DATE'; } //sort order of teaser articles if (strlen($this->aSettings['teaser_sort_order']) == 0) { $this->aSettings['teaser_sort_order'] = 'asc'; } //teaser image crop option if (strlen($this->aSettings['teaser_image_crop']) == 0 || $this->aSettings['teaser_image_crop'] == 'false') { $this->aSettings['teaser_image_crop'] = 'false'; } } /** * Function gets path to an image of base of idupload in contenido, * scales this image on basis of teaser settings and returns path to * scaled image. It is also possible to give path to image directly, * in this case set fourth parameter to true * * @param integer $iImage - idupl of image to use for teaser * @param integer $iMaxX - maximum image width * @param integer $iMaxY - maximum image height * @param boolean $bIsFile - in case of a direct file path retrival from database is not needed * @return string - tag contains scaled image * * @access private */ private function getImage($iImage, $iMaxX, $iMaxY, $bCropped, $bIsFile = false) { $sContent = ''; if ($bCropped == 'true') { $bCropped = true; } else { $bCropped = false; } //check if there is a need to get image path if ($bIsFile == false) { //get path out of database $sSQL = 'SELECT * FROM ' . $this->aCfg['tab']['upl'] . ' WHERE idupl = ' . $iImage; $this->oDb->query($sSQL); if ($this->oDb->next_record()) { $sTeaserImage = $this->aCfgClient[$this->iClient]['path']['frontend'] . 'upload/' . $this->oDb->f("dirname") . $this->oDb->f("filename"); } } else { $sTeaserImage = $iImage; } //scale image if exists and return it if (file_exists($sTeaserImage)) { //Scale Image using capiImgScale $sImgSrc = capiImgScale($sTeaserImage, $iMaxX, $iMaxY, $bCropped); if ($this->sUseXHTML == 'true') { $sLetter = ' /'; } else { $sLetter = ''; } //Put Image into the teasertext $sContent = '' . $sContent; } return $sContent; } /** * Function retrives name of an article by its id from database * * @param integer $iIdArt - Contenido article id * @return string - name of article * * @access private */ private function getArtName($iIdArt) { $iIdArt = (int) $iIdArt; //get article name from database $sSql = 'SELECT * FROM ' . $this->aCfg['tab']['art_lang'] . ' WHERE idart = ' . $iIdArt; $this->oDb->query($sSql); if ($this->oDb->next_record()) { return $this->oDb->f('title'); } else { return 'Unknown Article'; } } /** * Teaser allows to get a list of ids in which article content is searched in * article like 1,2,5,6 the result with largest character count is returned * * @param object $oArticle - Contenido article object * @param string $sIdType - Name of Content type to extract informations from * @param integer $iIdType - list of ids to search in * @return string - largest result of content * * @access private */ private function getArtContent(&$oArticle, $sIdType, $iIdType) { $sReturn = ''; //split ids, if there is only one id, array has only one place filled, that is also ok $aIds = explode(',', $iIdType); foreach ($aIds as $iCurIdType) { $sTmp = $oArticle->getContent($sIdType, $iCurIdType); //check for largest result and replace when new value is larger if (strlen($sReturn) < strlen($sTmp)) { $sReturn = $sTmp; } } return $sReturn; } /** * When a HTML Code is given for a Teaser image try to find a image in this code and generate * Teaser image on that basis * * @param string $sContent - HTML string to search image in * @return img tag containing scaled image * * @access private */ private function extractImage($sContent) { $sImage = ''; //search an image tag $sRegEx = "/]*?>.*?/i"; $aMatch = array(); preg_match($sRegEx, $sContent, $aMatch); //if found extract its src content $sRegEx = "/(src)(=)(['\"]?)([^\"']*)(['\"]?)/i"; $aImg = array(); preg_match($sRegEx, $aMatch[0], $aImg); //check if this image lies in upload folder $iPos = strrpos($aImg[4], $this->aCfgClient[$this->iClient]["upload"]); if (!is_bool($iPos)) { //if it is generate full internal path to image and scale it for display using class internal function getImage() $sFile = $this->aCfgClient[$this->iClient]['path']['frontend'] . $aImg[4]; $sImage = $this->getImage($sFile, $this->aSettings['teaser_image_width'], $this->aSettings['teaser_image_height'], $this->aSettings['teaser_image_crop'], true); } return $sImage; } /** * In edit and view mode this function fills teaser template with informations from an * Contenido article object * * @param object $oArticle - Contenido Article object * @param object $oTpl - Contenido Template object (as reference) * @return boolean - success state of this operation * * @access private */ private function fillTeaserTemplateEntry($oArticle, &$oTpl) { global $cCurrentModule; //get necessary informations for teaser from articles use properties in a Settings for retirval $sTitle = $this->getArtContent($oArticle, $this->aSettings['teaser_source_head'], $this->aSettings['teaser_source_head_count']); $sText = $this->getArtContent($oArticle, $this->aSettings['teaser_source_text'], $this->aSettings['teaser_source_text_count']); $iImage = $this->getArtContent($oArticle, $this->aSettings['teaser_source_image'], $this->aSettings['teaser_source_image_count']); $sDate = $this->getArtContent($oArticle, $this->aSettings['teaser_source_date'], $this->aSettings['teaser_source_date_count']); $iIdArt = $oArticle->getField('idart'); $iPublished = $oArticle->getField('published'); $iOnline = $oArticle->getField('online'); if ($iOnline == 1) { //teaserfilter defines strings which must be contained in text for display. //if string is defined check if article contains this string and abort, if article does not contain this string if ($this->aSettings['teaser_filter'] != '') { $iPosText = strrpos(clHtmlEntityDecode($sText), $this->aSettings['teaser_filter']); $iPosHead = strrpos(clHtmlEntityDecode($sTitle), $this->aSettings['teaser_filter']); if (is_bool($iPosText) && !$iPosText && is_bool($iPosHead) && !$iPosHead) { return false; } } //convert date to readable format if (preg_match('/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/', $iPublished, $aResults)) { $iPublished = $aResults[3] . '.' . $aResults[2] . '.' . $aResults[1]; } //strip tags in teaser text and cut it if it is to long $sTitle = trim(strip_tags($sTitle)); $sText = trim(strip_tags($sText)); if (strlen($sText) > $this->aSettings['teaser_character_limit']) { $sText = capiStrTrimAfterWord($sText, $this->aSettings['teaser_character_limit']) . '...'; } //try to get a teaser image directly from cms_img or try to extract if a content type is given, wich contains html if ((int) $iImage > 0) { $sImage = $this->getImage($iImage, $this->aSettings['teaser_image_width'], $this->aSettings['teaser_image_height'], $this->aSettings['teaser_image_crop']); $oTpl->set('d', 'IMAGE', $sImage); } else if (strip_tags($iImage) != $iImage && strlen($iImage) > 0) { $sImage = $this->extractImage($iImage); if (strlen($sImage) > 0) { $oTpl->set('d', 'IMAGE', $sImage); } else { $oTpl->set('d', 'IMAGE', ''); } } else { $oTpl->set('d', 'IMAGE', ''); } // strip all tags from manual teaser date $sDate = strip_tags($sDate); //set generated values to teaser template $oTpl->set('d', 'TITLE', $sTitle); $oTpl->set('d', 'TEXT', $sText); $oTpl->set('d', 'IDART', $iIdArt); $oTpl->set('d', 'ART_URL', 'front_content.php?idart=' . $iIdArt); $oTpl->set('d', 'PUBLISHED', $iPublished); $oTpl->set('d', 'PUBLISHED_MANUAL', $sDate); if ($sDate != "") { $oTpl->set('d', 'PUBLISHED_COMBINED', $sDate); } else { $oTpl->set('d', 'PUBLISHED_COMBINED', $iPublished); } foreach (self::$aTranslations as $sKey => $sValue) { $oTpl->set('d', $sKey, mi18n($sValue)); } $oTpl->next(); } return true; } /** * Function is called in edit- and viewmode in order to generate teasercode for output * * @param boolean $bEditmode - in editmode skip encoding because it is done in getAllWidgetEdit() * @return html string of select box * * @access public */ public function getAllWidgetOutput($bEditmode = false) { $oTpl = new Template(); //set title of teaser $oTpl->set('s', 'TITLE', $this->aSettings['teaser_title']); //decide if it is a manual or category teaser if ($this->aSettings['teaser_manual'] == 'true' && count($this->aSettings['teaser_manual_art']) > 0) { $i = 0; //in manual case get all art to display and generate article objects manually foreach ($this->aSettings['teaser_manual_art'] as $iIdArt) { $oArticle = new Article($iIdArt, $this->iClient, $this->iLang); //try to fill teaser image if ($this->fillTeaserTemplateEntry($oArticle, $oTpl)) { $i++; //break render, if teaser limit is reached if ($i == $this->aSettings['teaser_count']) break; } } } else { //in case of autmatic teaser use class Contenido_Category_Articles for getting all arts in category $oConCatArt = new Contenido_Category_Articles($this->oDb, $this->aCfg, $this->iClient, $this->iLang); //decide to teaser articles or not if ($this->aSettings['teaser_start'] == 'true') { $aArticles = $oConCatArt->getArticlesInCategory($this->aSettings['teaser_category'], $this->aSettings['teaser_sort'], $this->aSettings['teaser_sort_order']); } else { $aArticles = $oConCatArt->getNonStartArticlesInCategory($this->aSettings['teaser_category'], $this->aSettings['teaser_sort'], $this->aSettings['teaser_sort_order']); } $i = 0; //iterate over all found articles foreach ($aArticles as $oArticle) { //try to fill teaser image if ($this->fillTeaserTemplateEntry($oArticle, $oTpl)) { $i++; //break render, if teaser limit is reached if ($i == $this->aSettings['teaser_count']) break; } } } $sCode = ''; //generate teasertemplate if (file_exists($this->aCfgClient[$this->iClient]['path']['frontend'] . 'templates/' . $this->aSettings['teaser_style'])) { $sCode = $oTpl->generate($this->aCfgClient[$this->iClient]['path']['frontend'] . 'templates/' . $this->aSettings['teaser_style'], 1); } return $sCode; //use this to show xml document which contains teaser settings #return '
'.clHtmlEntities($this->sContent).'
'; } /** * Dynamic filelist generator. * This method is executed every time the filelist is displayed. * * @return string output of the filelist */ public function getAllWidgetView() { $sCode = '\";?>getAllWidgetOutput(); ?>sContent, $this->iId); return $sCode; } } ?>