HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/PvdBoogaard/indoorski.nl/backup/oude-site/cms/api/class.contenttypes.php
<?php
/**
 * This file contains the iwp_content_types class
 *
 * @version $Id$
 * 
 *
 * @package IWP
 * @subpackage IWP_API
 */

/**
 * IWP Content Types Class
 * This class extends the iwp_engine abstract class.
 * This class handles all operations pertaining to the content types table
 *
 * @package IWP
 * @subpackage IWP_API
 * @property iwp_contentvars $vars
 */
class iwp_contenttypes extends iwp_engine {
	/**
	 * This static variable contains permissions that are available to be chosen for setting Content Type permissions. This is the base list of permission options that all custom content types inherit. The list is later merged with options specific to any (field) modules that are added to the content type.
	 *
	 * @var Array
	 */
	public static $PermissionOptions;

	/**
	 * primaryKey
	 * This is the name of the field that is the primary key for this table. It is a private and final variable
	 *
	 * @var primaryKey
	 **/
	protected $primaryKey = 'typeid';

	/**
	 * baseTableName
	 * This is the name of the table without its prefix. This is a final private class variable and cannot be changed.
	 *
	 * @var baseTableName
	 **/
	protected $baseTableName = 'content_types';

	/**
	 * _columns
	 * This is the final structure of the table in use. It can not be changed after this declaration.
	 *
	 * @var _columns
	 *
	 * @see ValidColumn
	 **/
	protected $_columns = array(
							'name' => '',
							'name_singular' => '',
							'defaulturl' => '',
							'modulelist' => '',
							'cachetime' => '',
							'cacheunit' => '',
							'searchable' => '',
							'typeicon' => '',
							'field_expiryoptions' => 0,
							'field_hidefrommenu' => 0,
							'field_status' => 0,
							'field_startdate' => 0,
							'field_visible' => 0,
						);
	/**
	 * data
	 * The data array of the current row held in the class memory. It should be the same structure as _columns.
	 *
	 * @var data
	 *
	 * @see Save
	 * @see Load
	 * @see LoadMulti
	 **/
	protected $data = array();

	/**
	 * This is a multidimensional associative array of the currently available fields for this content type
	 *
	 * @var array
	 *
	 * @see Load()
	 * @see GetFieldsList()
	 */
	public $availableFieldsList = array();

	/**
	 * This is a single dimensional array of all the fields this content type has, useful for checking for a particular field
	 *
	 * @var array
	 *
	 * @see FlattenFieldsArray()
	 * @see Load()
	 * @see GetFieldsList()
	 */
	public $flatAvailableFieldsList = array();

	/**
	 * validation
	 * The array of validation functions to apply to the data values whenever we save to the database.
	 *
	 * @var validation
	 *
	 * @see Save
	 * @see iwp_validation
	 **/
	protected $validation = array(
							'name' => array('FilterAlphaNumeric', 'FilterLimit255', 'IsNotBlank'),
							'name_singular' => array('FilterAlphaNumeric', 'FilterLimit255', 'IsNotBlank'),
							'modulelist' => array('FilterCSVText'),
						);

	/**
	 * Instance
	 * This static variable holds the current instance of this object being loaded.
	 * So using the getInstance function anywhere will return the very same instance.
	 *
	 * @var object Instance
	 */
	public static $Instance;

	/**
	 * getInstance
	 * This is a static function that sets up the class instance and stores it to the static variable. It will then return that instantiation in the future.
	 *
	 * @return iwp_contenttypes Returns the instantiated object
	 **/
	public static function getInstance(){
		if(!isset(self::$Instance)){
			self::$Instance = new self();
		}
		return self::$Instance;
	}

	/**
	 * This function returns the PermissionOptions variable
	 *
	 * @return array The value of $PermissionOptions
	 */

	public static function GetPermissionOptions () {
		return self::$PermissionOptions;
	}

	/**
	 * __construct
	 * The class contructor. Call the parent constructor then reset the data columns
	 *
	 * @return void
	**/
	public function __construct(){
		parent::__construct();
		$this->ResetColumns();
	}

	/**
	 * LoadNew
	 * Create a new empty content-type with $name as its name, urlfolder, and templatefile name
	 *
	 * @param $name string This is the name of the new content type. It can only be alphanumeric
	 *
	 * @return void
	 *
	 * @see data
	 * @see Exists
	 * @see Save
	**/
	public function LoadNew($name){
		$name = $this->valid->FilterAlphaNumeric($name);
		if(is_blank($name)){
			return false;
		}

		if(!$this->Exists('name', $name)){
			$this->data['name'] = $name;
			$this->data['defaulturl'] = '{title}.html';
			$this->Save();
		}

		return true;
	}

	/**
	* Save
	* Calls the parent save function to save object information to the database and updates necessary cache files.
	*
	* @return boolean True if the data was saved, false if it wasn't and there was an error
	*/
	public function Save () {
		$result = parent::Save();

		if ($result) {
			// it's more efficient to clear all the cache files than to work out which individual cache files need clearing
			// such a process tends to time out or exceed memory usage on website with tens of thousands of content items
			$cache = iwp_cache::getInstance();
			$cache->ClearCacheAll();
		}

		return $result;
	}

	/**
	 * Load
	 * Calls the parent load function to load the data base on an id, and sets up the content vars object too
	 *
	 * @param $id integer The id number of the content-type to load
	 *
	 * @return void
	**/
	public function Load($id=null){
		if(parent::Load($id)){
			$this->vars = new iwp_contentvars();
			$this->vars->Load($id);
			$this->SetId($id);
			if(strlen($this->Get('modulelist')) > 0){
				$this->flatAvailableFieldsList = $this->FlattenFieldsArray($this->GetFieldsList());
			}
			return true;
		}else{
			return false;
		}
	}

	/**
	 * This function takes a structured tabs-groups-fields array and serialises it into a string for saving into the database.
	 * It is the reverse function of ExplodeFields()
	 *
	 * <code>
	 * // an example array
	 * $array['Tab Name'] = array( 'Group Name'=> array('title', 'content'));
	 *
	 * </code>
	 *
	 * @param array $array The tabs-groups-fields array to implode
	 *
	 * @return string A imploded/serialised version of the array passed in
	 *
	 * @see ExplodeFields()
	 * @see FlattenFieldsArray()
	 */

	public function ImplodeFields($array){
		$strClean = '';
		foreach($array as $tab=>$group){
			$grpResult = array();
			foreach($group as $groupName=>$fields){
				$grpResult[] = $groupName .'|' .implode(',', $fields);
			}
			$tabResult[] = $tab.'='.implode('^^',$grpResult);
		}
		$strClean = implode('::', $tabResult);
		return $strClean;
	}

	/**
	 * This function takes a serialised tabs-groups-fields string and explodes it into an array.
	 * It is the reverse function of ImplodeFields()
	 *
	 * @param string $string The tabs-groups-fields string to explode into an array
	 *
	 * @return array A multi-dimensional tabs-groups-fields array
	 *
	 * @see ImplodeFields()
	 * @see FlattenFieldsArray()
	 */

	public function ExplodeFields($string){
		$arrClean = array();
		$tabs = $this->valid->FilterCleanArray(explode('::',$string));
		foreach($tabs as $k=>$str){
			if($str == '=') { continue; }
			$tabBits = $this->valid->FilterCleanArray(explode('=', $str));
			$arrClean[$tabBits[0]] = array();
			$groups = $this->valid->FilterCleanArray(explode('^^', $tabBits[1]));
			foreach($groups as $k2=>$gStr){
				$gBits = explode('|', $gStr);
				$arrClean[$tabBits[0]][$gBits[0]] = array();
				$fields = explode(',', $gBits[1]);
				$fields = $this->valid->FilterCleanArray($fields);
				$fields = array_map('trim', $fields);
				$arrClean[$tabBits[0]][$gBits[0]] = $fields;
			}
		}
		return $arrClean;
	}

	/**
	 * This function takes a tabs-groups-fields array and extracts all the fields into a single dimension array
	 *
	 * @param array $fieldsGroupedArray The tabs-groups-fields array to extract the fields from
	 *
	 * @return array A single dimension array of fields
	 *
	 * @see ImplodeFields()
	 * @see ExplodeFields()
	 */
	public function FlattenFieldsArray($fieldsGroupedArray){
		$fieldsList = array();
		foreach($fieldsGroupedArray as $tab=>$arrGroup){
			foreach($arrGroup as $group=>$arrFields){
				if(is_array($arrFields) && sizeof($arrFields) > 0){
					$fieldsList = array_merge($fieldsList, $arrFields);
				}
			}
		}
		return $fieldsList;
	}


	/**
	 * This delete function calls the parent to delete the content type but then calls the vars object to delete all the content vars associated with this content type
	 *
	 * @return boolean True if successful, false otherwise
	 */
	public function Delete () {
		$id = $this->GetId();
		if ($id < 1) {
			return false;
		}

		if (parent::Delete()) {
			if ($this->vars->DeleteAll($id)) {
				iwp_content::getInstance()->DeleteContentType($id);
				iwp_admin_lists::getInstance()->DeleteContentType($id);
				return true;
			} else {
				return false;
			}
		} else {
			return false;
		}
	}

	/**
	* Returns an array of lists that are related to a given content type by checking the filters of lists. The array returned contains list ids as keys and list titles as values.
	*
	* @param integer $id
	* @return array
	*/
	public static function GetListsForContentType ($typeId) {
		$contentTypes = iwp_contenttypes::getInstance();
		$sql = sprintf("SELECT /* iwp_contenttypes::GetListsForContentType */ l.listid, l.title FROM %s l WHERE (SELECT COUNT(*) FROM %s f WHERE f.listid = l.listid AND f.filtertype = 'where' AND f.operator = 'iscontenttype' AND f.value = '%d') > 0", IWP_TABLE_LISTS, IWP_TABLE_LIST_FILTERS, $typeId);
		$resource = $contentTypes->db->Query($sql);
		$return = array();
		while ($row = $contentTypes->db->Fetch($resource)) {
			$return[(int)$row['listid']] = $row['title'];
		}
		return $return;
	}

	/**
	* Returns an array of list ids that are related to this content type by checking the filters of lists. The array returned contains list ids as keys and list titles as values.
	*
	* @return array
	*/
	public function GetLists () {
		return self::GetListsForContentType($this->GetId());
	}

	/**
	 * This returns an array of the current list of fields for the current content item
	 *
	 * @return array The an array in the Tabs-Groups-Fields array format
	 *
	 * @see ExplodeFields()
	 */
	public function GetFieldsList(){
		if(!$this->ValidId()){
			return array();
		}

		if (sizeof($this->availableFieldsList) == 0) {
			$this->availableFieldsList = $this->ExplodeFields($this->Get('modulelist'));
		}

		return $this->availableFieldsList;
	}

	/**
	 * This checks to see if the field passed in is in the list of fields for the current content type
	 *
	 * @return boolean True if it exists, false otherwise
	 *
	 * @see GetFieldsList()
	 */
	public function IsField($field){
		return in_array($field, $this->FlattenFieldsArray($this->GetFieldsList()));
	}

	/**
	 * This function returns the default values for a specified field
	 *
	 * @param string $field The name of the field to get the default value for
	 *
	 * @return string The default value of the field
	 */
	public function GetFieldDefaultValue($field){
		foreach($this->FieldList as $_key=>$v) {
			foreach($v['fields'] as $k=>$fields) {
				if($k == $field && isset($fields['default'])){
					return $fields['default'];
				}
			}
		}

		return '';
	}

	/**
	 * SetContentVar
	 * Sets a content-type variable through the content_vars object
	 *
	 * @param $name string The name of the variable to set
	 * @param $value string The value of the variable to set
	 * @param $moduleid string The moduleid of the variable to set, this can be zero if its a general variable
	 *
	 * @return void
	**/
	public function SetContentVar($name, $value, $moduleid=0){
		$this->vars->Set($name, $value, $this->GetId(), $moduleid);
	}

	/**
	 * This is an overload function that is called when a requested variable doesn't exist. Its used to automatically load the contentvars class
	 * If any other variable is called its passed to the iwp_base overload __get() function
	 * This function should never be called directly
	 *
	 * @param string $name The name of the variable being requested
	 *
	 * @return object The instance of the requested object
	 */
	public function __get($name){
		if($name == "vars"){
			$this->vars = new iwp_contentvars();
			return $this->vars;
		}else{
			return parent::__get($name);
		}
	}

	/**
	 * GetContentVar
	 * Gets a content-type variable through the content_vars object based on its name
	 *
	 * @param $name string The name of the variable to get
	 * @param $moduleid string The moduleid of the variable to get, this can be zero if its a general variable. Note: Modules might have variables that have the same name.
	 *
	 * @return mixed The value of the contenttype variable
	**/
	public function GetContentVar($name,$moduleid=0){
		return $this->vars->Get($name, $this->GetId() , $moduleid);
	}

	/**
	 * DeleteContentVar
	 * This calls the delete function in the content_vars class and adds in the typeid as the second field.
	 *
	 * @param $name string The name of the content variable to delete
	 * @param $moduleid string The moduleid number of the content variable to delete
	 *
	 * @return void
	**/
	public function DeleteContentVar($name, $moduleid=0){
		return $this->vars->Delete($name, $this->GetId(), $moduleid);
	}

	/**
	 * Returns a granularity list for this class.
	 *
	 * @param Integer $total Total will be populated with number of rows found in query (by reference)
	 * @param String $filter Filter string, optional
	 * @param Integer $page Page number of records to return, optional
	 * @return Array List of value/text pairs
	 */
	public static function getGranularityList (&$total, &$page, $filter = '')
	{
		$limitStart = ($page * IWP_PERMISSIONGRANULARITEMS_PER_PAGE) - IWP_PERMISSIONGRANULARITEMS_PER_PAGE;
		$where = '';
		if ($filter) {
			$filter = '%'. self::getInstance()->db->Quote($filter) .'%';
			$where = sprintf("WHERE (`name` LIKE '%s')", $filter);
		}
		$result = self::getInstance()->db->Query(sprintf("SELECT SQL_CALC_FOUND_ROWS typeid AS `value`, `name` AS `text` FROM %s %s ORDER BY `name` LIMIT %d, %d", IWP_TABLE_CONTENTTYPES, $where, $limitStart, IWP_PERMISSIONGRANULARITEMS_PER_PAGE));
		$total = self::getInstance()->db->FetchOne('SELECT found_rows()');
		$list = array();
		if ($result) {
			while ($row = self::getInstance()->db->Fetch($result)) {
				$row['value'] = (int)$row['value'];
				array_push($list, $row);
			}
			self::getInstance()->db->FreeResult($result);
		}
		return $list;
	}

	/**
	 * Returns a list of content titles for a supplied list of content IDs
	 *
	 * @param Array $ids
	 * @return array
	 */
	public static function GetTitleList ($ids)
	{
		$list = array();
		if (count($ids)) {
			$me = self::getInstance();
			$sql = sprintf("SELECT typeid as `value`, `name` as `text` FROM %s WHERE typeid IN (%s) ORDER BY `name`", IWP_TABLE_CONTENTTYPES, implode(',', $ids));
			$result = $me->db->Query($sql);
			while ($row = $me->db->Fetch($result)) {
				$row['value'] = (int)$row['value'];
				array_push($list, $row);
			}
		}
		return $list;
	}

	/**
	 * This function generates a URL for a content item based on the format for this content type, replacing all the placeholders with values
	 *
	 * @param iwp_content $instanceContent An instance of the content item to generate the URL for
	 * @param integer $id The ID number of the content item to generate the URL for
	 * @param string $titleAddition This string is appended to the title, useful when there are duplicate URLs and a number can be attached
	 *
	 * @return string The final version of the URL string, ready for use and saving
	 */
	public function GetUrlForContentItem($instanceContent=null, $id=null, $titleAddition=''){

		if(!iwp_IsId($id) && is_null($instanceContent)){
			return '';
		}

		if(iwp_IsId($id) && is_null($instanceContent)){
			$instanceContent = new iwp_content();
			$instanceContent->Load($id);
		}

		$url = $this->Get('defaulturl');

		// all the content replacements
		$url = str_replace('{contentid}',	(int)$instanceContent->GetId(),	$url);
		$url = str_replace('{title}',		iwp_strtolower($this->urls->RemoveBadCharacters($instanceContent->Get('title'))) . $titleAddition,	$url);
		$url = str_replace('{meta-title}',	iwp_strtolower($this->urls->RemoveBadCharacters($instanceContent->Get('metatitle'))),	$url);

		// do all the date replacements
		$datestamp = strtotime($instanceContent->Get('startdate'));

		$url = str_replace(array('{date-eu}','{date-eu-dot}'),	iwp_strtolower($this->urls->ReplaceSpaces(date('d.m.Y', $datestamp))),	$url);
		$url = str_replace('{date-eu-slash}',					iwp_strtolower($this->urls->ReplaceSpaces(date('d/m/Y', $datestamp))),	$url);

		$url = str_replace(array('{date-us}','{date-us-slash}'),iwp_strtolower($this->urls->ReplaceSpaces(date('m/d/Y', $datestamp))),	$url);
		$url = str_replace('{date-us-dot}',						iwp_strtolower($this->urls->ReplaceSpaces(date('m.d.Y', $datestamp))),	$url);

		$url = str_replace('{day-number-short}',	iwp_strtolower($this->urls->ReplaceSpaces(date('j', $datestamp))),	$url);
		$url = str_replace('{day-number-long}',		iwp_strtolower($this->urls->ReplaceSpaces(date('d', $datestamp))),	$url);
		$url = str_replace('{day-name-long}',		iwp_strtolower($this->urls->ReplaceSpaces(date('l', $datestamp))),	$url);
		$url = str_replace('{day-name-short}',		iwp_strtolower($this->urls->ReplaceSpaces(date('d', $datestamp))),	$url);
		$url = str_replace('{day-ordinal}',			iwp_strtolower($this->urls->ReplaceSpaces(date('S', $datestamp))),	$url);

		$url = str_replace('{month-number-long}',	iwp_strtolower($this->urls->ReplaceSpaces(date('m', $datestamp))),	$url);
		$url = str_replace('{month-number-short}',	iwp_strtolower($this->urls->ReplaceSpaces(date('n', $datestamp))),	$url);
		$url = str_replace('{month-name-long}',		iwp_strtolower($this->urls->ReplaceSpaces(date('F', $datestamp))),	$url);
		$url = str_replace('{month-name-short}',	iwp_strtolower($this->urls->ReplaceSpaces(date('M', $datestamp))),	$url);

		$url = str_replace('{year-short}',			iwp_strtolower($this->urls->ReplaceSpaces(date('y', $datestamp))),	$url);
		$url = str_replace('{year-long}',			iwp_strtolower($this->urls->ReplaceSpaces(date('Y', $datestamp))),	$url);

		$url = str_replace('{hour-12-long}',		iwp_strtolower($this->urls->ReplaceSpaces(date('h', $datestamp))),	$url);
		$url = str_replace('{hour-12-short}',		iwp_strtolower($this->urls->ReplaceSpaces(date('g', $datestamp))),	$url);

		$url = str_replace('{hour-24-short}',		iwp_strtolower($this->urls->ReplaceSpaces(date('H', $datestamp))),	$url);
		$url = str_replace('{hour-24-long}',		iwp_strtolower($this->urls->ReplaceSpaces(date('G', $datestamp))),	$url);

		$url = str_replace('{minutes}',			iwp_strtolower($this->urls->ReplaceSpaces(date('i', $datestamp))),	$url);

		$url = str_replace('{ampm}',				iwp_strtolower($this->urls->ReplaceSpaces(date('a', $datestamp))),	$url);
		$url = str_replace('{internet-time}',		iwp_strtolower($this->urls->ReplaceSpaces(date('B', $datestamp))),	$url);
		$url = str_replace('{timestamp}',			iwp_strtolower($this->urls->ReplaceSpaces($datestamp)),	$url);

		return $url;
	}

	/**
	 * This function returns either 'An' or 'A' depending English rules based on the first word of the provided string.
	 *
	 * @param string $string
	 * @return string
	 */
	public static function GetAnOrA ($string) {
		list($firstWord) = explode(' ', trim($string), 2);
		$firstWordUpperCase = iwp_strtoupper($firstWord);

		//	specific search list for words with a silent H that should be shown as "An {Word}"
		$silents = array('HOMAGE', 'HOUR', 'HONEST', 'HONOR', 'HEIR');
		if (in_array($firstWordUpperCase, $silents)) {
			return 'An';
		}

		//	specific search for words beginning with Uk such as Ukulele, Ukraine - these words begin with a 'yoo' sound
		if (substr($firstWordUpperCase, 0, 2) == 'UK') {
			return 'A';
		}

		//	specific search for words beginning with Uni such as Union, University - these words begin with a 'yoo' sound
		if (substr($firstWordUpperCase, 0, 3) == 'UNI') {
			return 'A';
		}

		$firstLetter = substr($firstWordUpperCase, 0, 1);

		//	words that begin with a vowel which were not handled above
		$vowels = array('A', 'E', 'I', 'O', 'U');
		if (in_array($firstLetter, $vowels)) {
			return 'An';
		}

		//	acronyms that begin with a letter with a vowel-like sound
		$firstLetterUpperCase = iwp_strtoupper($firstLetter);
		$vowels = array('A', 'E', 'F', 'H', 'I', 'L', 'M', 'N', 'O', 'S', 'X');
		if ($firstWord === $firstWordUpperCase && in_array($firstLetterUpperCase, $vowels)) {
			return 'An';
		}

		return 'A';
	}
}

/**
 * These are the permission options available for this class
 */
iwp_contenttypes::$PermissionOptions = array(
	'full'		=> new iwp_permissionoption(true, false, false),
	'create'	=> new iwp_permissionoption(false, false, false),
	'delete'	=> new iwp_permissionoption(true, false, false),
	'edit'		=> new iwp_permissionoption(true, false, false)
);