<?php
/**
* Part of Showkase web site management package
*
* @package Showkase
* @author Jack Hardie {@link http://www.jhardie.com}
* @copyright Copyright (c) 2014, SimpleViewer Inc.
*/
defined('SK_ACCESS')||die('<h1>403: Forbidden</h1>');
require_once "classes{$ds}fieldfactory.php";
require_once "classes{$ds}layerwriter.php";
/**
* Site, Theme, Viewer, Page are layers
* Fields are piped through the layers
*
* @package Showkase
*/
abstract class Layer
{
/**
* @var array of field objects to appear in the layer customize screen
*
*/
protected $layerFields = array();
/**
* @var array of default values from layer ini file
*/
protected $layerDefaults = array();
/**
* @var array of incoming fields from previous layer
*/
protected $incomingFields = array();
/**
* @var array of field objects accumulated from this and previous layers
*/
protected $accumulatedFields = array();
/**
* @var string path to settings file
*/
protected $settingsPath;
/**
* @var object Themeset
*/
protected $themeSet;
/**
* get array of field objects from ini file
*
* @param string path to file
* @return array of field objects or false for unsupported page type
*/
/*
protected function readFieldsIni($path)
{
$fields = array();
if (!file_exists($path)) throw new Exception('Cannot find '.basename($path));
$iniVars = parse_ini_file($path, true);
if ($iniVars === false) throw new Exception('Cannot read '.basename($path));
foreach ($iniVars as $name => $var) {
if (!is_array($var)) throw new Exception('Error in ini file: '.$name.' is not an array');
$fields[$name] = FieldFactory::make($var + array('name'=>$name));
}
return $fields;
}
*/
/**
* get array of field objects from ini file
*
* @param array of paths to theme and parent ini files
* @return array of field objects or false for unsupported page type
*/
protected function readFieldInis(array $paths)
{
$themeIniVars = array();
$parentIniVars = array();
$fields = array();
if (!empty($paths['parent'])) {
$parentIniVars = parse_ini_file($paths['parent'], true);
if ($parentIniVars === false) throw new Exception('Cannot read parent theme ini file '.basename($$paths['parent']));
}
if (file_exists($paths['theme'])) {
$themeIniVars = parse_ini_file($paths['theme'], true);
}
if ($themeIniVars === false) throw new Exception('Cannot read theme ini file '.basename($paths['theme']));
// parent theme determines order in customize pages
$union = $parentIniVars + $themeIniVars;
foreach ($union as $name => $var) {
if (!is_array($var)) throw new Exception('Error in ini file: '.$name.' is not an array');
$fieldVars = array();
if (isset($parentIniVars[$name])) {
$fieldVars = $parentIniVars[$name];
if (isset($themeIniVars[$name])) {
$fieldVars = array_merge($parentIniVars[$name], $themeIniVars[$name]);
}
}
else {
$fieldVars = $themeIniVars[$name];
}
$fields[$name] = FieldFactory::make($fieldVars + array('name'=>$name));
}
return $fields;
}
/**
* Merge data from xml file into field objects
* Data will be merged if current layer has a variable to receive the data
* Or a new non-exposed text field will be created to carry the settings forward
* The fields array must be passed by reference to add elements
*
* @param array of field objects
* @param array of theme or page settings
* @param array of deprecated settings as array('oldname', 'newname')
* @return void
*/
protected function loadFields(array &$fields, array $settings, array $deprecated = array())
{
foreach ($deprecated as $old=>$new) {
if (
isset($settings[$old])
&& !isset($settings[$new])
) {
$settings[$new] = $settings[$old];
}
unset($settings[$old]);
}
foreach ($settings as $name=>$value) {
if (isset($fields[$name])) {
$fields[$name]->setValue($value);
continue;
}
$fields[$name] = FieldFactory::make(
array(
'name' =>$name,
'type' =>'text',
'exposed'=>'false',
'value' =>$value
)
);
}
}
/**
* Merge incoming field objects with local objects from ini file
* Incoming values and local structure have precedence
*
* @return array of field objects
* @param field objects from ini file (local level)
* @param field objects accumulated from previous layers (upper level)
*/
protected function mergeFields(array $iniFields, array $accumulatedFields)
{
$intersect = array_intersect_key($iniFields, $accumulatedFields);
foreach ($intersect as $name=>$field) {
$iniFields[$name]->setValue($accumulatedFields[$name]->getValue());
}
//return $iniFields + $accumulatedFields;
return $iniFields;
}
/** Clean data from form and update class properties
*
* @return array containing keys of changed fields
* @param array as $_POST. Need not contain all settings.
*/
protected function updateFields($fields, $newSettings)
{
if (!is_array($newSettings) || count($newSettings) == 0) return array();
$oldFields = array();
$changes = array();
foreach ($fields as $name=>$field) {
$oldFields[$name] = clone $field;
if (!isset($newSettings[$name])) continue;
// fix for CKEditor adding Windows line endings
$newValue = trim(str_replace(array("\r\n", "\n", "\r"), PHP_EOL, $newSettings[$name]));
if ($field->type() == 'rgbacolor') {
$newValue = array($newValue, $newSettings[$name.'Alpha']);
}
$fields[$name]->setValue($newValue);
if ($oldFields[$name]->getValue() != $fields[$name]->getValue()) $changes[] = $name;
}
return $changes;
}
/**
* Get a single layer var value
* Does not include accumulated fields
*
* @param string page var name
* @return string or null if not found
*/
public function getLayerVar($name, $colorPrefix = '')
{
$fields = $this->getLayerFields();
if (!isset($fields[$name])) return null;
$prefix =
$fields[$name]->type() == 'hexcolor'
? $colorPrefix
: '';
return $colorPrefix.$fields[$name]->getValue();
}
/** Clean data from form and update class properties
*
* @return array containing keys of changed fields
* @param array as $_POST. Need not contain all settings.
*/
public function customize($newSettings)
{
if (!is_array($newSettings) || count($newSettings) == 0) return array();
$oldLayerFields = array();
$layerFields = $this->layerFields;
$changes = array();
foreach ($layerFields as $name=>$field) {
$oldLayerFields[$name] = clone $field;
if (!isset($newSettings[$name])) continue;
// fix for CKEditor adding Windows line endings
$newValue = trim(str_replace(array("\r\n", "\n", "\r"), PHP_EOL, $newSettings[$name]));
if ($field->type() == 'rgbacolor') {
$newValue = array($newValue, $newSettings[$name.'Alpha']);
}
$this->layerFields[$name]->setValue($newValue);
if ($oldLayerFields[$name]->getValue() != $layerFields[$name]->getValue()) $changes[] = $name;
}
return $changes;
}
/**
* returns instance of theme set
*/
public function getThemeSet()
{
return $this->themeSet;
}
/**
* returns page type
*
* @return string
*/
public function getPageType()
{
return $this->pageType;
}
/**
* Get page ref
*
* @return string
*/
public function getRef()
{
return $this->pageRef;
}
/**
* Get relative path
*
* @return string
*/
public function getPagePathRelSvm()
{
return $this->pagePathRelSvm;
}
/**
* Get path to settings file
*
* @return string
*/
public function getSettingsPath()
{
return $this->settingsPath;
}
/**
* Get layer fields
*
* @return array of field objects
*/
public function getLayerFields()
{
return $this->layerFields;
}
/**
* Get incoming fields from previous layer
*
* @return array of field objects
*/
public function getIncomingFields()
{
return $this->incomingFields;
}
/**
* Get outgoing fields to next layer
*
* @return array of field objects
*/
public function getAccumulatedFields()
{
return $this->accumulatedFields;
}
/**
* Save to xml file
*
* @param string file name
* @return void
*/
public function saveLayer()
{
try {
LayerWriter::writeLayerVars($this);
} catch (Exception $e) {
throw new Exception('Data not saved. '.$e->getMessage());
}
}
}