mirror of
https://github.com/typemill/typemill.git
synced 2025-08-06 14:16:46 +02:00
Version 1.2.16
This commit is contained in:
@@ -1,286 +1,286 @@
|
||||
<?php
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
class Field
|
||||
{
|
||||
private $type;
|
||||
|
||||
private $label;
|
||||
|
||||
private $name;
|
||||
|
||||
private $content;
|
||||
|
||||
/* holds all simple attributes for this field like "required" */
|
||||
private $attributes = array();
|
||||
|
||||
/* holds all attribute value pairs for this field like "id=''" */
|
||||
private $attributeValues = array();
|
||||
|
||||
/* holds all options for this field (e.g. select options) */
|
||||
private $options = array();
|
||||
|
||||
/* defines all field types, that are allowed */
|
||||
private $types = array(
|
||||
'checkbox',
|
||||
'checkboxlist',
|
||||
'color',
|
||||
'date',
|
||||
'datetime',
|
||||
'datetime-local',
|
||||
'email',
|
||||
'file',
|
||||
'hidden',
|
||||
'image',
|
||||
'month',
|
||||
'number',
|
||||
'password',
|
||||
'radio',
|
||||
'range',
|
||||
'tel',
|
||||
'text',
|
||||
'time',
|
||||
'url',
|
||||
'week',
|
||||
'textarea',
|
||||
'select',
|
||||
'paragraph'
|
||||
);
|
||||
|
||||
/* defines all boolean attributes, that are allowed for fields */
|
||||
private $attr = array(
|
||||
'autofocus',
|
||||
'checked',
|
||||
'disabled',
|
||||
'formnovalidate',
|
||||
'multiple',
|
||||
'readonly',
|
||||
'required'
|
||||
);
|
||||
|
||||
/* defines all attribute value paires, that are allowed for fields */
|
||||
private $attrValues = array(
|
||||
'id',
|
||||
'autocomplete',
|
||||
'placeholder',
|
||||
'size',
|
||||
'rows',
|
||||
'cols',
|
||||
'min',
|
||||
'max',
|
||||
'class',
|
||||
'pattern'
|
||||
);
|
||||
|
||||
/* defines additional data, that are allowed for fields */
|
||||
private $helpers = array(
|
||||
'help',
|
||||
'description'
|
||||
);
|
||||
|
||||
public function __construct($fieldName, array $fieldConfigs)
|
||||
{
|
||||
$this->setName($fieldName);
|
||||
|
||||
$type = isset($fieldConfigs['type']) ? $fieldConfigs['type'] : false;
|
||||
$this->setType($type);
|
||||
|
||||
$label = isset($fieldConfigs['label']) ? $fieldConfigs['label'] : false;
|
||||
$this->setLabel($label);
|
||||
|
||||
$checkboxlabel = isset($fieldConfigs['checkboxlabel']) ? $fieldConfigs['checkboxlabel'] : false;
|
||||
$this->setCheckboxLabel($checkboxlabel);
|
||||
|
||||
$options = isset($fieldConfigs['options']) ? $fieldConfigs['options'] : array();
|
||||
$this->setOptions($options);
|
||||
|
||||
$this->setAttributes($fieldConfigs);
|
||||
|
||||
$this->setAttributeValues($fieldConfigs);
|
||||
|
||||
$this->setHelpers($fieldConfigs);
|
||||
}
|
||||
|
||||
private function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
private function setType($type)
|
||||
{
|
||||
if(in_array($type, $this->types))
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
}
|
||||
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function setLabel($label)
|
||||
{
|
||||
$this->label = $label;
|
||||
}
|
||||
|
||||
public function getLabel()
|
||||
{
|
||||
return $this->label;
|
||||
}
|
||||
|
||||
public function setCheckboxLabel($label)
|
||||
{
|
||||
$this->checkboxLabel = $label;
|
||||
}
|
||||
|
||||
public function getCheckboxLabel()
|
||||
{
|
||||
return $this->checkboxLabel;
|
||||
}
|
||||
|
||||
public function setContent($content)
|
||||
{
|
||||
$this->content = $content;
|
||||
}
|
||||
|
||||
public function getContent()
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
private function setOptions(array $options)
|
||||
{
|
||||
foreach($options as $key => $value)
|
||||
{
|
||||
$this->options[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
public function getOptions()
|
||||
{
|
||||
if(isset($this->options))
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function setAttributes($fieldConfigs)
|
||||
{
|
||||
foreach($fieldConfigs as $key => $value)
|
||||
{
|
||||
if(is_string($key) && in_array($key, $this->attr))
|
||||
{
|
||||
$this->attributes[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* get all attributes of the field and return them as a string. For usage in templates */
|
||||
public function getAttributes()
|
||||
{
|
||||
$string = false;
|
||||
|
||||
foreach($this->attributes as $key => $attribute)
|
||||
{
|
||||
$string .= ' ' . $key;
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/* set a single attribute. Used e.g. in controller to change the value */
|
||||
public function setAttribute($key, $value)
|
||||
{
|
||||
$this->attributes[$key] = $value;
|
||||
}
|
||||
|
||||
public function unsetAttribute($key)
|
||||
{
|
||||
unset($this->attributes[$key]);
|
||||
}
|
||||
|
||||
/* get a single attribute, if it is defined. For usage in templates like getAttribute('required') */
|
||||
public function getAttribute($key)
|
||||
{
|
||||
if(isset($this->attributes[$key]))
|
||||
{
|
||||
return $this->attributes[$key];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function setAttributeValues($fieldConfigs)
|
||||
{
|
||||
foreach($fieldConfigs as $key => $value)
|
||||
{
|
||||
if(is_string($key) && in_array($key, $this->attrValues))
|
||||
{
|
||||
$this->attributeValues[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* get all attributes as string. For usage in template */
|
||||
public function getAttributeValues()
|
||||
{
|
||||
$string = false;
|
||||
|
||||
foreach($this->attributeValues as $key => $attribute)
|
||||
{
|
||||
$string .= ' ' . $key . '="' . $attribute . '"';
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
public function setAttributeValue($key, $value)
|
||||
{
|
||||
/* pretty dirty, but you should not add a value for a simple checkbox */
|
||||
if($key == 'value' && $this->type == 'checkbox')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$this->attributeValues[$key] = $value;
|
||||
}
|
||||
|
||||
public function getAttributeValue($key)
|
||||
{
|
||||
if(isset($this->attributeValues[$key]))
|
||||
{
|
||||
return $this->attributeValues[$key];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public function setHelpers($fieldConfigs)
|
||||
{
|
||||
foreach($fieldConfigs as $key => $config)
|
||||
{
|
||||
if(is_string($key) && in_array($key, $this->helpers))
|
||||
{
|
||||
$this->$key = $config;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getHelper($helperName)
|
||||
{
|
||||
if(isset($this->$helperName))
|
||||
{
|
||||
return $this->$helperName;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
class Field
|
||||
{
|
||||
private $type;
|
||||
|
||||
private $label;
|
||||
|
||||
private $name;
|
||||
|
||||
private $content;
|
||||
|
||||
/* holds all simple attributes for this field like "required" */
|
||||
private $attributes = array();
|
||||
|
||||
/* holds all attribute value pairs for this field like "id=''" */
|
||||
private $attributeValues = array();
|
||||
|
||||
/* holds all options for this field (e.g. select options) */
|
||||
private $options = array();
|
||||
|
||||
/* defines all field types, that are allowed */
|
||||
private $types = array(
|
||||
'checkbox',
|
||||
'checkboxlist',
|
||||
'color',
|
||||
'date',
|
||||
'datetime',
|
||||
'datetime-local',
|
||||
'email',
|
||||
'file',
|
||||
'hidden',
|
||||
'image',
|
||||
'month',
|
||||
'number',
|
||||
'password',
|
||||
'radio',
|
||||
'range',
|
||||
'tel',
|
||||
'text',
|
||||
'time',
|
||||
'url',
|
||||
'week',
|
||||
'textarea',
|
||||
'select',
|
||||
'paragraph'
|
||||
);
|
||||
|
||||
/* defines all boolean attributes, that are allowed for fields */
|
||||
private $attr = array(
|
||||
'autofocus',
|
||||
'checked',
|
||||
'disabled',
|
||||
'formnovalidate',
|
||||
'multiple',
|
||||
'readonly',
|
||||
'required'
|
||||
);
|
||||
|
||||
/* defines all attribute value paires, that are allowed for fields */
|
||||
private $attrValues = array(
|
||||
'id',
|
||||
'autocomplete',
|
||||
'placeholder',
|
||||
'size',
|
||||
'rows',
|
||||
'cols',
|
||||
'min',
|
||||
'max',
|
||||
'class',
|
||||
'pattern'
|
||||
);
|
||||
|
||||
/* defines additional data, that are allowed for fields */
|
||||
private $helpers = array(
|
||||
'help',
|
||||
'description'
|
||||
);
|
||||
|
||||
public function __construct($fieldName, array $fieldConfigs)
|
||||
{
|
||||
$this->setName($fieldName);
|
||||
|
||||
$type = isset($fieldConfigs['type']) ? $fieldConfigs['type'] : false;
|
||||
$this->setType($type);
|
||||
|
||||
$label = isset($fieldConfigs['label']) ? $fieldConfigs['label'] : false;
|
||||
$this->setLabel($label);
|
||||
|
||||
$checkboxlabel = isset($fieldConfigs['checkboxlabel']) ? $fieldConfigs['checkboxlabel'] : false;
|
||||
$this->setCheckboxLabel($checkboxlabel);
|
||||
|
||||
$options = isset($fieldConfigs['options']) ? $fieldConfigs['options'] : array();
|
||||
$this->setOptions($options);
|
||||
|
||||
$this->setAttributes($fieldConfigs);
|
||||
|
||||
$this->setAttributeValues($fieldConfigs);
|
||||
|
||||
$this->setHelpers($fieldConfigs);
|
||||
}
|
||||
|
||||
private function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
private function setType($type)
|
||||
{
|
||||
if(in_array($type, $this->types))
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
}
|
||||
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function setLabel($label)
|
||||
{
|
||||
$this->label = $label;
|
||||
}
|
||||
|
||||
public function getLabel()
|
||||
{
|
||||
return $this->label;
|
||||
}
|
||||
|
||||
public function setCheckboxLabel($label)
|
||||
{
|
||||
$this->checkboxLabel = $label;
|
||||
}
|
||||
|
||||
public function getCheckboxLabel()
|
||||
{
|
||||
return $this->checkboxLabel;
|
||||
}
|
||||
|
||||
public function setContent($content)
|
||||
{
|
||||
$this->content = $content;
|
||||
}
|
||||
|
||||
public function getContent()
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
private function setOptions(array $options)
|
||||
{
|
||||
foreach($options as $key => $value)
|
||||
{
|
||||
$this->options[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
public function getOptions()
|
||||
{
|
||||
if(isset($this->options))
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function setAttributes($fieldConfigs)
|
||||
{
|
||||
foreach($fieldConfigs as $key => $value)
|
||||
{
|
||||
if(is_string($key) && in_array($key, $this->attr))
|
||||
{
|
||||
$this->attributes[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* get all attributes of the field and return them as a string. For usage in templates */
|
||||
public function getAttributes()
|
||||
{
|
||||
$string = false;
|
||||
|
||||
foreach($this->attributes as $key => $attribute)
|
||||
{
|
||||
$string .= ' ' . $key;
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/* set a single attribute. Used e.g. in controller to change the value */
|
||||
public function setAttribute($key, $value)
|
||||
{
|
||||
$this->attributes[$key] = $value;
|
||||
}
|
||||
|
||||
public function unsetAttribute($key)
|
||||
{
|
||||
unset($this->attributes[$key]);
|
||||
}
|
||||
|
||||
/* get a single attribute, if it is defined. For usage in templates like getAttribute('required') */
|
||||
public function getAttribute($key)
|
||||
{
|
||||
if(isset($this->attributes[$key]))
|
||||
{
|
||||
return $this->attributes[$key];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function setAttributeValues($fieldConfigs)
|
||||
{
|
||||
foreach($fieldConfigs as $key => $value)
|
||||
{
|
||||
if(is_string($key) && in_array($key, $this->attrValues))
|
||||
{
|
||||
$this->attributeValues[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* get all attributes as string. For usage in template */
|
||||
public function getAttributeValues()
|
||||
{
|
||||
$string = false;
|
||||
|
||||
foreach($this->attributeValues as $key => $attribute)
|
||||
{
|
||||
$string .= ' ' . $key . '="' . $attribute . '"';
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
public function setAttributeValue($key, $value)
|
||||
{
|
||||
/* pretty dirty, but you should not add a value for a simple checkbox */
|
||||
if($key == 'value' && $this->type == 'checkbox')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$this->attributeValues[$key] = $value;
|
||||
}
|
||||
|
||||
public function getAttributeValue($key)
|
||||
{
|
||||
if(isset($this->attributeValues[$key]))
|
||||
{
|
||||
return $this->attributeValues[$key];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public function setHelpers($fieldConfigs)
|
||||
{
|
||||
foreach($fieldConfigs as $key => $config)
|
||||
{
|
||||
if(is_string($key) && in_array($key, $this->helpers))
|
||||
{
|
||||
$this->$key = $config;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getHelper($helperName)
|
||||
{
|
||||
if(isset($this->$helperName))
|
||||
{
|
||||
return $this->$helperName;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -1,104 +1,104 @@
|
||||
<?php
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
use Typemill\Models\Field;
|
||||
|
||||
class Fields
|
||||
{
|
||||
public function getFields($userSettings, $objectType, $objectName, $objectSettings, $formType = false)
|
||||
{
|
||||
# hold all fields in array
|
||||
$fields = array();
|
||||
|
||||
# formtype are backend forms or public forms, only relevant for plugins for now
|
||||
$formType = $formType ? $formType : 'forms';
|
||||
|
||||
# iterate through all fields of the objectSetting (theme or plugin)
|
||||
foreach($objectSettings[$formType]['fields'] as $fieldName => $fieldConfigurations)
|
||||
{
|
||||
if($fieldConfigurations['type'] == 'fieldset')
|
||||
{
|
||||
# if it is a fieldset, then create a subset for the containing field and read them with a recursive function
|
||||
$subSettings = $objectSettings;
|
||||
$subSettings['forms'] = $fieldConfigurations;
|
||||
|
||||
$fieldset = array();
|
||||
$fieldset['type'] = 'fieldset';
|
||||
$fieldset['legend'] = $fieldConfigurations['legend'];
|
||||
$fieldset['fields'] = $this->getFields($userSettings, $objectType, $objectName, $subSettings, $formType);
|
||||
$fields[] = $fieldset;
|
||||
}
|
||||
else
|
||||
{
|
||||
# For label, helptext and description you can use the value of another field. This is useful e.g. to localize the label of public forms via plugin settings.
|
||||
if(isset($fieldConfigurations['label']) && isset($userSettings[$objectType][$objectName][$fieldConfigurations['label']]))
|
||||
{
|
||||
$fieldConfigurations['label'] = $userSettings[$objectType][$objectName][$fieldConfigurations['label']];
|
||||
}
|
||||
if(isset($fieldConfigurations['help']) && isset($userSettings[$objectType][$objectName][$fieldConfigurations['help']]))
|
||||
{
|
||||
$fieldConfigurations['help'] = $userSettings[$objectType][$objectName][$fieldConfigurations['help']];
|
||||
}
|
||||
if(isset($fieldConfigurations['description']) && isset($userSettings[$objectType][$objectName][$fieldConfigurations['description']]))
|
||||
{
|
||||
$fieldConfigurations['description'] = $userSettings[$objectType][$objectName][$fieldConfigurations['description']];
|
||||
}
|
||||
|
||||
# for each field generate a new field object with the field name and the field configurations
|
||||
$field = new Field($fieldName, $fieldConfigurations);
|
||||
|
||||
# handle the value for the field
|
||||
$userValue = false;
|
||||
|
||||
# first, add the default value from the original plugin or theme settings
|
||||
if(isset($objectSettings['settings'][$fieldName]))
|
||||
{
|
||||
$userValue = $objectSettings['settings'][$fieldName];
|
||||
}
|
||||
|
||||
# now overwrite the default values with the user values stored in the user settings
|
||||
if(isset($userSettings[$objectType][$objectName][$fieldName]))
|
||||
{
|
||||
$userValue = $userSettings[$objectType][$objectName][$fieldName];
|
||||
}
|
||||
|
||||
# now overwrite user-values, if there are old-input values from the actual form (e.g. after input error)
|
||||
if(isset($_SESSION['old'][$objectName][$fieldName]))
|
||||
{
|
||||
$userValue = $_SESSION['old'][$objectName][$fieldName];
|
||||
}
|
||||
|
||||
# Now prepopulate the field object with the value */
|
||||
if($field->getType() == "textarea" || $field->getType() == "paragraph")
|
||||
{
|
||||
if($userValue)
|
||||
{
|
||||
$field->setContent($userValue);
|
||||
}
|
||||
}
|
||||
elseif($field->getType() == "checkbox")
|
||||
{
|
||||
# checkboxes need a special treatment, because field does not exist in settings if unchecked by user
|
||||
if(isset($userSettings[$objectType][$objectName][$fieldName]))
|
||||
{
|
||||
$field->setAttribute('checked', 'true');
|
||||
}
|
||||
else
|
||||
{
|
||||
$field->unsetAttribute('chhecked');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$field->setAttributeValue('value', $userValue);
|
||||
}
|
||||
|
||||
# add the field to the field-List
|
||||
$fields[] = $field;
|
||||
|
||||
}
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
use Typemill\Models\Field;
|
||||
|
||||
class Fields
|
||||
{
|
||||
public function getFields($userSettings, $objectType, $objectName, $objectSettings, $formType = false)
|
||||
{
|
||||
# hold all fields in array
|
||||
$fields = array();
|
||||
|
||||
# formtype are backend forms or public forms, only relevant for plugins for now
|
||||
$formType = $formType ? $formType : 'forms';
|
||||
|
||||
# iterate through all fields of the objectSetting (theme or plugin)
|
||||
foreach($objectSettings[$formType]['fields'] as $fieldName => $fieldConfigurations)
|
||||
{
|
||||
if($fieldConfigurations['type'] == 'fieldset')
|
||||
{
|
||||
# if it is a fieldset, then create a subset for the containing field and read them with a recursive function
|
||||
$subSettings = $objectSettings;
|
||||
$subSettings['forms'] = $fieldConfigurations;
|
||||
|
||||
$fieldset = array();
|
||||
$fieldset['type'] = 'fieldset';
|
||||
$fieldset['legend'] = $fieldConfigurations['legend'];
|
||||
$fieldset['fields'] = $this->getFields($userSettings, $objectType, $objectName, $subSettings, $formType);
|
||||
$fields[] = $fieldset;
|
||||
}
|
||||
else
|
||||
{
|
||||
# For label, helptext and description you can use the value of another field. This is useful e.g. to localize the label of public forms via plugin settings.
|
||||
if(isset($fieldConfigurations['label']) && isset($userSettings[$objectType][$objectName][$fieldConfigurations['label']]))
|
||||
{
|
||||
$fieldConfigurations['label'] = $userSettings[$objectType][$objectName][$fieldConfigurations['label']];
|
||||
}
|
||||
if(isset($fieldConfigurations['help']) && isset($userSettings[$objectType][$objectName][$fieldConfigurations['help']]))
|
||||
{
|
||||
$fieldConfigurations['help'] = $userSettings[$objectType][$objectName][$fieldConfigurations['help']];
|
||||
}
|
||||
if(isset($fieldConfigurations['description']) && isset($userSettings[$objectType][$objectName][$fieldConfigurations['description']]))
|
||||
{
|
||||
$fieldConfigurations['description'] = $userSettings[$objectType][$objectName][$fieldConfigurations['description']];
|
||||
}
|
||||
|
||||
# for each field generate a new field object with the field name and the field configurations
|
||||
$field = new Field($fieldName, $fieldConfigurations);
|
||||
|
||||
# handle the value for the field
|
||||
$userValue = false;
|
||||
|
||||
# first, add the default value from the original plugin or theme settings
|
||||
if(isset($objectSettings['settings'][$fieldName]))
|
||||
{
|
||||
$userValue = $objectSettings['settings'][$fieldName];
|
||||
}
|
||||
|
||||
# now overwrite the default values with the user values stored in the user settings
|
||||
if(isset($userSettings[$objectType][$objectName][$fieldName]))
|
||||
{
|
||||
$userValue = $userSettings[$objectType][$objectName][$fieldName];
|
||||
}
|
||||
|
||||
# now overwrite user-values, if there are old-input values from the actual form (e.g. after input error)
|
||||
if(isset($_SESSION['old'][$objectName][$fieldName]))
|
||||
{
|
||||
$userValue = $_SESSION['old'][$objectName][$fieldName];
|
||||
}
|
||||
|
||||
# Now prepopulate the field object with the value */
|
||||
if($field->getType() == "textarea" || $field->getType() == "paragraph")
|
||||
{
|
||||
if($userValue)
|
||||
{
|
||||
$field->setContent($userValue);
|
||||
}
|
||||
}
|
||||
elseif($field->getType() == "checkbox")
|
||||
{
|
||||
# checkboxes need a special treatment, because field does not exist in settings if unchecked by user
|
||||
if(isset($userSettings[$objectType][$objectName][$fieldName]))
|
||||
{
|
||||
$field->setAttribute('checked', 'true');
|
||||
}
|
||||
else
|
||||
{
|
||||
$field->unsetAttribute('chhecked');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$field->setAttributeValue('value', $userValue);
|
||||
}
|
||||
|
||||
# add the field to the field-List
|
||||
$fields[] = $field;
|
||||
|
||||
}
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
}
|
@@ -1,434 +1,434 @@
|
||||
<?php
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
use \URLify;
|
||||
|
||||
class Folder
|
||||
{
|
||||
|
||||
/*
|
||||
* scans content of a folder (without recursion)
|
||||
* vars: folder path as string
|
||||
* returns: one-dimensional array with names of folders and files
|
||||
*/
|
||||
public static function scanFolderFlat($folderPath)
|
||||
{
|
||||
$folderItems = scandir($folderPath);
|
||||
$folderContent = array();
|
||||
|
||||
foreach ($folderItems as $key => $item)
|
||||
{
|
||||
if (!in_array($item, array(".","..")))
|
||||
{
|
||||
$nameParts = self::getStringParts($item);
|
||||
$fileType = array_pop($nameParts);
|
||||
|
||||
if($fileType == 'md' OR $fileType == 'txt' )
|
||||
{
|
||||
$folderContent[] = $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $folderContent;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* scans content of a folder recursively
|
||||
* vars: folder path as string
|
||||
* returns: multi-dimensional array with names of folders and files
|
||||
*/
|
||||
public static function scanFolder($folderPath, $draft = false)
|
||||
{
|
||||
$folderItems = scandir($folderPath);
|
||||
$folderContent = array();
|
||||
|
||||
# if it is the live version and if it is a folder that is not published, then do not show the folder and its content.
|
||||
if(!$draft && !in_array('index.md', $folderItems)){ return false; }
|
||||
|
||||
foreach ($folderItems as $key => $item)
|
||||
{
|
||||
if (!in_array($item, array(".","..")))
|
||||
{
|
||||
if (is_dir($folderPath . DIRECTORY_SEPARATOR . $item))
|
||||
{
|
||||
$subFolder = $item;
|
||||
$folderContent[$subFolder] = self::scanFolder($folderPath . DIRECTORY_SEPARATOR . $subFolder, $draft);
|
||||
}
|
||||
else
|
||||
{
|
||||
$nameParts = self::getStringParts($item);
|
||||
$fileType = array_pop($nameParts);
|
||||
|
||||
if($fileType == 'md')
|
||||
{
|
||||
$folderContent[] = $item;
|
||||
}
|
||||
|
||||
if($draft === true && $fileType == 'txt')
|
||||
{
|
||||
if(isset($last) && ($last == implode($nameParts)) )
|
||||
{
|
||||
array_pop($folderContent);
|
||||
$item = $item . 'md';
|
||||
}
|
||||
$folderContent[] = $item;
|
||||
}
|
||||
|
||||
/* store the name of the last file */
|
||||
$last = implode($nameParts);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $folderContent;
|
||||
}
|
||||
|
||||
/*
|
||||
* Transforms array of folder item into an array of item-objects with additional information for each item
|
||||
* vars: multidimensional array with folder- and file-names
|
||||
* returns: array of objects. Each object contains information about an item (file or folder).
|
||||
*/
|
||||
public static function getFolderContentDetails(array $folderContent, $baseUrl, $fullSlugWithFolder = NULL, $fullSlugWithoutFolder = NULL, $fullPath = NULL, $keyPath = NULL, $chapter = NULL)
|
||||
{
|
||||
$contentDetails = [];
|
||||
$iteration = 0;
|
||||
$chapternr = 1;
|
||||
|
||||
foreach($folderContent as $key => $name)
|
||||
{
|
||||
$item = new \stdClass();
|
||||
|
||||
if(is_array($name))
|
||||
{
|
||||
$nameParts = self::getStringParts($key);
|
||||
|
||||
$fileType = '';
|
||||
if(in_array('index.md', $name))
|
||||
{
|
||||
$fileType = 'md';
|
||||
$status = 'published';
|
||||
}
|
||||
if(in_array('index.txt', $name))
|
||||
{
|
||||
$fileType = 'txt';
|
||||
$status = 'unpublished';
|
||||
}
|
||||
if(in_array('index.txtmd', $name))
|
||||
{
|
||||
$fileType = 'txt';
|
||||
$status = 'modified';
|
||||
}
|
||||
|
||||
$item->originalName = $key;
|
||||
$item->elementType = 'folder';
|
||||
$item->status = $status;
|
||||
$item->fileType = $fileType;
|
||||
$item->order = count($nameParts) > 1 ? array_shift($nameParts) : NULL;
|
||||
$item->name = implode(" ",$nameParts);
|
||||
$item->name = iconv(mb_detect_encoding($item->name, mb_detect_order(), true), "UTF-8", $item->name);
|
||||
$item->slug = implode("-",$nameParts);
|
||||
$item->slug = URLify::filter(iconv(mb_detect_encoding($item->slug, mb_detect_order(), true), "UTF-8", $item->slug));
|
||||
$item->path = $fullPath . DIRECTORY_SEPARATOR . $key;
|
||||
$item->urlRelWoF = $fullSlugWithoutFolder . '/' . $item->slug;
|
||||
$item->urlRel = $fullSlugWithFolder . '/' . $item->slug;
|
||||
$item->urlAbs = $baseUrl . $fullSlugWithoutFolder . '/' . $item->slug;
|
||||
$item->key = $iteration;
|
||||
$item->keyPath = isset($keyPath) ? $keyPath . '.' . $iteration : $iteration;
|
||||
$item->keyPathArray = explode('.', $item->keyPath);
|
||||
$item->chapter = $chapter ? $chapter . '.' . $chapternr : $chapternr;
|
||||
$item->active = false;
|
||||
$item->activeParent = false;
|
||||
|
||||
$item->folderContent = self::getFolderContentDetails($name, $baseUrl, $item->urlRel, $item->urlRelWoF, $item->path, $item->keyPath, $item->chapter);
|
||||
}
|
||||
else
|
||||
{
|
||||
# do not use files in base folder (only folders are allowed)
|
||||
if(!isset($keyPath)) continue;
|
||||
|
||||
# do not use index files
|
||||
if($name == 'index.md' || $name == 'index.txt' || $name == 'index.txtmd' ) continue;
|
||||
|
||||
$nameParts = self::getStringParts($name);
|
||||
$fileType = array_pop($nameParts);
|
||||
|
||||
if($fileType == 'md')
|
||||
{
|
||||
$status = 'published';
|
||||
}
|
||||
elseif($fileType == 'txt')
|
||||
{
|
||||
$status = 'unpublished';
|
||||
}
|
||||
else
|
||||
{
|
||||
$fileType = 'txt';
|
||||
$status = 'modified';
|
||||
}
|
||||
|
||||
$item->originalName = $name;
|
||||
$item->elementType = 'file';
|
||||
$item->status = $status;
|
||||
$item->fileType = $fileType;
|
||||
$item->order = count($nameParts) > 1 ? array_shift($nameParts) : NULL;
|
||||
$item->name = implode(" ",$nameParts);
|
||||
$item->name = iconv(mb_detect_encoding($item->name, mb_detect_order(), true), "UTF-8", $item->name);
|
||||
$item->slug = implode("-",$nameParts);
|
||||
$item->slug = URLify::filter(iconv(mb_detect_encoding($item->slug, mb_detect_order(), true), "UTF-8", $item->slug));
|
||||
$item->path = $fullPath . DIRECTORY_SEPARATOR . $name;
|
||||
$item->key = $iteration;
|
||||
$item->keyPath = $keyPath . '.' . $iteration;
|
||||
$item->keyPathArray = explode('.',$item->keyPath);
|
||||
$item->chapter = $chapter . '.' . $chapternr;
|
||||
$item->urlRelWoF = $fullSlugWithoutFolder . '/' . $item->slug;
|
||||
$item->urlRel = $fullSlugWithFolder . '/' . $item->slug;
|
||||
$item->urlAbs = $baseUrl . $fullSlugWithoutFolder . '/' . $item->slug;
|
||||
$item->active = false;
|
||||
$item->activeParent = false;
|
||||
}
|
||||
$iteration++;
|
||||
$chapternr++;
|
||||
$contentDetails[] = $item;
|
||||
}
|
||||
return $contentDetails;
|
||||
}
|
||||
|
||||
public static function getItemForUrl($folderContentDetails, $url, $result = NULL)
|
||||
{
|
||||
foreach($folderContentDetails as $key => $item)
|
||||
{
|
||||
if($item->urlRel === $url)
|
||||
{
|
||||
# set item active, needed for move item in navigation
|
||||
$item->active = true;
|
||||
$result = $item;
|
||||
}
|
||||
elseif($item->elementType === "folder")
|
||||
{
|
||||
$result = self::getItemForUrl($item->folderContent, $url, $result);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function getPagingForItem($content, $item)
|
||||
{
|
||||
$keyPos = count($item->keyPathArray)-1;
|
||||
$thisChapArray = $item->keyPathArray;
|
||||
$nextItemArray = $item->keyPathArray;
|
||||
$prevItemArray = $item->keyPathArray;
|
||||
|
||||
$item->thisChapter = false;
|
||||
$item->prevItem = false;
|
||||
$item->nextItem = false;
|
||||
|
||||
|
||||
/************************
|
||||
* ADD THIS CHAPTER *
|
||||
************************/
|
||||
|
||||
if($keyPos > 0)
|
||||
{
|
||||
array_pop($thisChapArray);
|
||||
$item->thisChapter = self::getItemWithKeyPath($content, $thisChapArray);
|
||||
}
|
||||
|
||||
/************************
|
||||
* ADD NEXT ITEM *
|
||||
************************/
|
||||
|
||||
if($item->elementType == 'folder')
|
||||
{
|
||||
/* get the first element in the folder */
|
||||
$item->nextItem = isset($item->folderContent[0]) ? clone($item->folderContent[0]) : false;
|
||||
}
|
||||
|
||||
if(!$item->nextItem)
|
||||
{
|
||||
$nextItemArray[$keyPos]++;
|
||||
$item->nextItem = self::getItemWithKeyPath($content, $nextItemArray);
|
||||
}
|
||||
|
||||
while(!$item->nextItem)
|
||||
{
|
||||
array_pop($nextItemArray);
|
||||
if(empty($nextItemArray)) break;
|
||||
$newKeyPos = count($nextItemArray)-1;
|
||||
$nextItemArray[$newKeyPos]++;
|
||||
$item->nextItem = self::getItemWithKeyPath($content, $nextItemArray);
|
||||
}
|
||||
|
||||
/************************
|
||||
* ADD PREVIOUS ITEM *
|
||||
************************/
|
||||
|
||||
if($prevItemArray[$keyPos] > 0)
|
||||
{
|
||||
$prevItemArray[$keyPos]--;
|
||||
$item->prevItem = self::getItemWithKeyPath($content, $prevItemArray);
|
||||
|
||||
if($item->prevItem && $item->prevItem->elementType == 'folder' && !empty($item->prevItem->folderContent))
|
||||
{
|
||||
/* get last item in folder */
|
||||
$item->prevItem = self::getLastItemOfFolder($item->prevItem);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$item->prevItem = $item->thisChapter;
|
||||
}
|
||||
|
||||
if($item->prevItem && $item->prevItem->elementType == 'folder'){ unset($item->prevItem->folderContent); }
|
||||
if($item->nextItem && $item->nextItem->elementType == 'folder'){ unset($item->nextItem->folderContent); }
|
||||
if($item->thisChapter){unset($item->thisChapter->folderContent); }
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets a copy of an item with a key
|
||||
* @param array $content with the full structure of the content as multidimensional array
|
||||
* @param array $searchArray with the key as a one-dimensional array like array(0,3,4)
|
||||
* @return array $item
|
||||
*/
|
||||
|
||||
public static function getItemWithKeyPath($content, array $searchArray)
|
||||
{
|
||||
$item = false;
|
||||
|
||||
foreach($searchArray as $key => $itemKey)
|
||||
{
|
||||
$item = isset($content[$itemKey]) ? clone($content[$itemKey]) : false;
|
||||
|
||||
unset($searchArray[$key]);
|
||||
if(!empty($searchArray) && $item)
|
||||
{
|
||||
return self::getItemWithKeyPath($item->folderContent, $searchArray);
|
||||
}
|
||||
}
|
||||
return $item;
|
||||
}
|
||||
|
||||
# https://www.quora.com/Learning-PHP-Is-there-a-way-to-get-the-value-of-multi-dimensional-array-by-specifying-the-key-with-a-variable
|
||||
# NOT IN USE
|
||||
public static function getItemWithKeyPathNew($array, array $keys)
|
||||
{
|
||||
$item = $array;
|
||||
|
||||
foreach ($keys as $key)
|
||||
{
|
||||
$item = isset($item[$key]->folderContent) ? $item[$key]->folderContent : $item[$key];
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extracts an item with a key https://stackoverflow.com/questions/52097092/php-delete-value-of-array-with-dynamic-key
|
||||
* @param array $content with the full structure of the content as multidimensional array
|
||||
* @param array $searchArray with the key as a one-dimensional array like array(0,3,4)
|
||||
* @return array $item
|
||||
* NOT IN USE ??
|
||||
*/
|
||||
|
||||
public static function extractItemWithKeyPath($structure, array $keys)
|
||||
{
|
||||
$result = &$structure;
|
||||
$last = array_pop($keys);
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if(isset($result[$key]->folderContent))
|
||||
{
|
||||
$result = &$result[$key]->folderContent;
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = &$result[$key];
|
||||
}
|
||||
}
|
||||
|
||||
$item = $result[$last];
|
||||
unset($result[$last]);
|
||||
|
||||
return array('structure' => $structure, 'item' => $item);
|
||||
}
|
||||
|
||||
/* get breadcrumb as copied array, set elements active in original and mark parent element in original */
|
||||
public static function getBreadcrumb($content, $searchArray, $i = NULL, $breadcrumb = NULL)
|
||||
{
|
||||
if(!$i){ $i = 0; $breadcrumb = array();}
|
||||
|
||||
while($i < count($searchArray))
|
||||
{
|
||||
$item = $content[$searchArray[$i]];
|
||||
|
||||
if($i == count($searchArray)-1)
|
||||
{
|
||||
$item->active = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$item->activeParent = true;
|
||||
}
|
||||
/*
|
||||
$item->active = true;
|
||||
if($i == count($searchArray)-2)
|
||||
{
|
||||
$item->activeParent = true;
|
||||
}
|
||||
*/
|
||||
|
||||
$copy = clone($item);
|
||||
if($copy->elementType == 'folder')
|
||||
{
|
||||
unset($copy->folderContent);
|
||||
$content = $item->folderContent;
|
||||
}
|
||||
$breadcrumb[] = $copy;
|
||||
|
||||
$i++;
|
||||
return self::getBreadcrumb($content, $searchArray, $i++, $breadcrumb);
|
||||
}
|
||||
return $breadcrumb;
|
||||
}
|
||||
|
||||
public static function getParentItem($content, $searchArray, $iteration = NULL)
|
||||
{
|
||||
if(!$iteration){ $iteration = 0; }
|
||||
while($iteration < count($searchArray)-2)
|
||||
{
|
||||
$content = $content[$searchArray[$iteration]]->folderContent;
|
||||
$iteration++;
|
||||
return self::getParentItem($content, $searchArray, $iteration);
|
||||
}
|
||||
return $content[$searchArray[$iteration]];
|
||||
}
|
||||
|
||||
private static function getLastItemOfFolder($folder)
|
||||
{
|
||||
$lastItem = end($folder->folderContent);
|
||||
if(is_object($lastItem) && $lastItem->elementType == 'folder' && !empty($lastItem->folderContent))
|
||||
{
|
||||
return self::getLastItemOfFolder($lastItem);
|
||||
}
|
||||
return $lastItem;
|
||||
}
|
||||
|
||||
public static function getStringParts($name)
|
||||
{
|
||||
return preg_split('/[\-\.\_\=\+\?\!\*\#\(\)\/ ]/',$name);
|
||||
}
|
||||
|
||||
public static function getFileType($fileName)
|
||||
{
|
||||
$parts = preg_split('/\./',$fileName);
|
||||
return end($parts);
|
||||
}
|
||||
|
||||
public static function splitFileName($fileName)
|
||||
{
|
||||
$parts = preg_split('/\./',$fileName);
|
||||
return $parts;
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
use \URLify;
|
||||
|
||||
class Folder
|
||||
{
|
||||
|
||||
/*
|
||||
* scans content of a folder (without recursion)
|
||||
* vars: folder path as string
|
||||
* returns: one-dimensional array with names of folders and files
|
||||
*/
|
||||
public static function scanFolderFlat($folderPath)
|
||||
{
|
||||
$folderItems = scandir($folderPath);
|
||||
$folderContent = array();
|
||||
|
||||
foreach ($folderItems as $key => $item)
|
||||
{
|
||||
if (!in_array($item, array(".","..")))
|
||||
{
|
||||
$nameParts = self::getStringParts($item);
|
||||
$fileType = array_pop($nameParts);
|
||||
|
||||
if($fileType == 'md' OR $fileType == 'txt' )
|
||||
{
|
||||
$folderContent[] = $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $folderContent;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* scans content of a folder recursively
|
||||
* vars: folder path as string
|
||||
* returns: multi-dimensional array with names of folders and files
|
||||
*/
|
||||
public static function scanFolder($folderPath, $draft = false)
|
||||
{
|
||||
$folderItems = scandir($folderPath);
|
||||
$folderContent = array();
|
||||
|
||||
# if it is the live version and if it is a folder that is not published, then do not show the folder and its content.
|
||||
if(!$draft && !in_array('index.md', $folderItems)){ return false; }
|
||||
|
||||
foreach ($folderItems as $key => $item)
|
||||
{
|
||||
if (!in_array($item, array(".","..")))
|
||||
{
|
||||
if (is_dir($folderPath . DIRECTORY_SEPARATOR . $item))
|
||||
{
|
||||
$subFolder = $item;
|
||||
$folderContent[$subFolder] = self::scanFolder($folderPath . DIRECTORY_SEPARATOR . $subFolder, $draft);
|
||||
}
|
||||
else
|
||||
{
|
||||
$nameParts = self::getStringParts($item);
|
||||
$fileType = array_pop($nameParts);
|
||||
|
||||
if($fileType == 'md')
|
||||
{
|
||||
$folderContent[] = $item;
|
||||
}
|
||||
|
||||
if($draft === true && $fileType == 'txt')
|
||||
{
|
||||
if(isset($last) && ($last == implode($nameParts)) )
|
||||
{
|
||||
array_pop($folderContent);
|
||||
$item = $item . 'md';
|
||||
}
|
||||
$folderContent[] = $item;
|
||||
}
|
||||
|
||||
/* store the name of the last file */
|
||||
$last = implode($nameParts);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $folderContent;
|
||||
}
|
||||
|
||||
/*
|
||||
* Transforms array of folder item into an array of item-objects with additional information for each item
|
||||
* vars: multidimensional array with folder- and file-names
|
||||
* returns: array of objects. Each object contains information about an item (file or folder).
|
||||
*/
|
||||
public static function getFolderContentDetails(array $folderContent, $baseUrl, $fullSlugWithFolder = NULL, $fullSlugWithoutFolder = NULL, $fullPath = NULL, $keyPath = NULL, $chapter = NULL)
|
||||
{
|
||||
$contentDetails = [];
|
||||
$iteration = 0;
|
||||
$chapternr = 1;
|
||||
|
||||
foreach($folderContent as $key => $name)
|
||||
{
|
||||
$item = new \stdClass();
|
||||
|
||||
if(is_array($name))
|
||||
{
|
||||
$nameParts = self::getStringParts($key);
|
||||
|
||||
$fileType = '';
|
||||
if(in_array('index.md', $name))
|
||||
{
|
||||
$fileType = 'md';
|
||||
$status = 'published';
|
||||
}
|
||||
if(in_array('index.txt', $name))
|
||||
{
|
||||
$fileType = 'txt';
|
||||
$status = 'unpublished';
|
||||
}
|
||||
if(in_array('index.txtmd', $name))
|
||||
{
|
||||
$fileType = 'txt';
|
||||
$status = 'modified';
|
||||
}
|
||||
|
||||
$item->originalName = $key;
|
||||
$item->elementType = 'folder';
|
||||
$item->status = $status;
|
||||
$item->fileType = $fileType;
|
||||
$item->order = count($nameParts) > 1 ? array_shift($nameParts) : NULL;
|
||||
$item->name = implode(" ",$nameParts);
|
||||
$item->name = iconv(mb_detect_encoding($item->name, mb_detect_order(), true), "UTF-8", $item->name);
|
||||
$item->slug = implode("-",$nameParts);
|
||||
$item->slug = URLify::filter(iconv(mb_detect_encoding($item->slug, mb_detect_order(), true), "UTF-8", $item->slug));
|
||||
$item->path = $fullPath . DIRECTORY_SEPARATOR . $key;
|
||||
$item->urlRelWoF = $fullSlugWithoutFolder . '/' . $item->slug;
|
||||
$item->urlRel = $fullSlugWithFolder . '/' . $item->slug;
|
||||
$item->urlAbs = $baseUrl . $fullSlugWithoutFolder . '/' . $item->slug;
|
||||
$item->key = $iteration;
|
||||
$item->keyPath = isset($keyPath) ? $keyPath . '.' . $iteration : $iteration;
|
||||
$item->keyPathArray = explode('.', $item->keyPath);
|
||||
$item->chapter = $chapter ? $chapter . '.' . $chapternr : $chapternr;
|
||||
$item->active = false;
|
||||
$item->activeParent = false;
|
||||
|
||||
$item->folderContent = self::getFolderContentDetails($name, $baseUrl, $item->urlRel, $item->urlRelWoF, $item->path, $item->keyPath, $item->chapter);
|
||||
}
|
||||
else
|
||||
{
|
||||
# do not use files in base folder (only folders are allowed)
|
||||
if(!isset($keyPath)) continue;
|
||||
|
||||
# do not use index files
|
||||
if($name == 'index.md' || $name == 'index.txt' || $name == 'index.txtmd' ) continue;
|
||||
|
||||
$nameParts = self::getStringParts($name);
|
||||
$fileType = array_pop($nameParts);
|
||||
|
||||
if($fileType == 'md')
|
||||
{
|
||||
$status = 'published';
|
||||
}
|
||||
elseif($fileType == 'txt')
|
||||
{
|
||||
$status = 'unpublished';
|
||||
}
|
||||
else
|
||||
{
|
||||
$fileType = 'txt';
|
||||
$status = 'modified';
|
||||
}
|
||||
|
||||
$item->originalName = $name;
|
||||
$item->elementType = 'file';
|
||||
$item->status = $status;
|
||||
$item->fileType = $fileType;
|
||||
$item->order = count($nameParts) > 1 ? array_shift($nameParts) : NULL;
|
||||
$item->name = implode(" ",$nameParts);
|
||||
$item->name = iconv(mb_detect_encoding($item->name, mb_detect_order(), true), "UTF-8", $item->name);
|
||||
$item->slug = implode("-",$nameParts);
|
||||
$item->slug = URLify::filter(iconv(mb_detect_encoding($item->slug, mb_detect_order(), true), "UTF-8", $item->slug));
|
||||
$item->path = $fullPath . DIRECTORY_SEPARATOR . $name;
|
||||
$item->key = $iteration;
|
||||
$item->keyPath = $keyPath . '.' . $iteration;
|
||||
$item->keyPathArray = explode('.',$item->keyPath);
|
||||
$item->chapter = $chapter . '.' . $chapternr;
|
||||
$item->urlRelWoF = $fullSlugWithoutFolder . '/' . $item->slug;
|
||||
$item->urlRel = $fullSlugWithFolder . '/' . $item->slug;
|
||||
$item->urlAbs = $baseUrl . $fullSlugWithoutFolder . '/' . $item->slug;
|
||||
$item->active = false;
|
||||
$item->activeParent = false;
|
||||
}
|
||||
$iteration++;
|
||||
$chapternr++;
|
||||
$contentDetails[] = $item;
|
||||
}
|
||||
return $contentDetails;
|
||||
}
|
||||
|
||||
public static function getItemForUrl($folderContentDetails, $url, $result = NULL)
|
||||
{
|
||||
foreach($folderContentDetails as $key => $item)
|
||||
{
|
||||
if($item->urlRel === $url)
|
||||
{
|
||||
# set item active, needed for move item in navigation
|
||||
$item->active = true;
|
||||
$result = $item;
|
||||
}
|
||||
elseif($item->elementType === "folder")
|
||||
{
|
||||
$result = self::getItemForUrl($item->folderContent, $url, $result);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function getPagingForItem($content, $item)
|
||||
{
|
||||
$keyPos = count($item->keyPathArray)-1;
|
||||
$thisChapArray = $item->keyPathArray;
|
||||
$nextItemArray = $item->keyPathArray;
|
||||
$prevItemArray = $item->keyPathArray;
|
||||
|
||||
$item->thisChapter = false;
|
||||
$item->prevItem = false;
|
||||
$item->nextItem = false;
|
||||
|
||||
|
||||
/************************
|
||||
* ADD THIS CHAPTER *
|
||||
************************/
|
||||
|
||||
if($keyPos > 0)
|
||||
{
|
||||
array_pop($thisChapArray);
|
||||
$item->thisChapter = self::getItemWithKeyPath($content, $thisChapArray);
|
||||
}
|
||||
|
||||
/************************
|
||||
* ADD NEXT ITEM *
|
||||
************************/
|
||||
|
||||
if($item->elementType == 'folder')
|
||||
{
|
||||
/* get the first element in the folder */
|
||||
$item->nextItem = isset($item->folderContent[0]) ? clone($item->folderContent[0]) : false;
|
||||
}
|
||||
|
||||
if(!$item->nextItem)
|
||||
{
|
||||
$nextItemArray[$keyPos]++;
|
||||
$item->nextItem = self::getItemWithKeyPath($content, $nextItemArray);
|
||||
}
|
||||
|
||||
while(!$item->nextItem)
|
||||
{
|
||||
array_pop($nextItemArray);
|
||||
if(empty($nextItemArray)) break;
|
||||
$newKeyPos = count($nextItemArray)-1;
|
||||
$nextItemArray[$newKeyPos]++;
|
||||
$item->nextItem = self::getItemWithKeyPath($content, $nextItemArray);
|
||||
}
|
||||
|
||||
/************************
|
||||
* ADD PREVIOUS ITEM *
|
||||
************************/
|
||||
|
||||
if($prevItemArray[$keyPos] > 0)
|
||||
{
|
||||
$prevItemArray[$keyPos]--;
|
||||
$item->prevItem = self::getItemWithKeyPath($content, $prevItemArray);
|
||||
|
||||
if($item->prevItem && $item->prevItem->elementType == 'folder' && !empty($item->prevItem->folderContent))
|
||||
{
|
||||
/* get last item in folder */
|
||||
$item->prevItem = self::getLastItemOfFolder($item->prevItem);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$item->prevItem = $item->thisChapter;
|
||||
}
|
||||
|
||||
if($item->prevItem && $item->prevItem->elementType == 'folder'){ unset($item->prevItem->folderContent); }
|
||||
if($item->nextItem && $item->nextItem->elementType == 'folder'){ unset($item->nextItem->folderContent); }
|
||||
if($item->thisChapter){unset($item->thisChapter->folderContent); }
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets a copy of an item with a key
|
||||
* @param array $content with the full structure of the content as multidimensional array
|
||||
* @param array $searchArray with the key as a one-dimensional array like array(0,3,4)
|
||||
* @return array $item
|
||||
*/
|
||||
|
||||
public static function getItemWithKeyPath($content, array $searchArray)
|
||||
{
|
||||
$item = false;
|
||||
|
||||
foreach($searchArray as $key => $itemKey)
|
||||
{
|
||||
$item = isset($content[$itemKey]) ? clone($content[$itemKey]) : false;
|
||||
|
||||
unset($searchArray[$key]);
|
||||
if(!empty($searchArray) && $item)
|
||||
{
|
||||
return self::getItemWithKeyPath($item->folderContent, $searchArray);
|
||||
}
|
||||
}
|
||||
return $item;
|
||||
}
|
||||
|
||||
# https://www.quora.com/Learning-PHP-Is-there-a-way-to-get-the-value-of-multi-dimensional-array-by-specifying-the-key-with-a-variable
|
||||
# NOT IN USE
|
||||
public static function getItemWithKeyPathNew($array, array $keys)
|
||||
{
|
||||
$item = $array;
|
||||
|
||||
foreach ($keys as $key)
|
||||
{
|
||||
$item = isset($item[$key]->folderContent) ? $item[$key]->folderContent : $item[$key];
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extracts an item with a key https://stackoverflow.com/questions/52097092/php-delete-value-of-array-with-dynamic-key
|
||||
* @param array $content with the full structure of the content as multidimensional array
|
||||
* @param array $searchArray with the key as a one-dimensional array like array(0,3,4)
|
||||
* @return array $item
|
||||
* NOT IN USE ??
|
||||
*/
|
||||
|
||||
public static function extractItemWithKeyPath($structure, array $keys)
|
||||
{
|
||||
$result = &$structure;
|
||||
$last = array_pop($keys);
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if(isset($result[$key]->folderContent))
|
||||
{
|
||||
$result = &$result[$key]->folderContent;
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = &$result[$key];
|
||||
}
|
||||
}
|
||||
|
||||
$item = $result[$last];
|
||||
unset($result[$last]);
|
||||
|
||||
return array('structure' => $structure, 'item' => $item);
|
||||
}
|
||||
|
||||
/* get breadcrumb as copied array, set elements active in original and mark parent element in original */
|
||||
public static function getBreadcrumb($content, $searchArray, $i = NULL, $breadcrumb = NULL)
|
||||
{
|
||||
if(!$i){ $i = 0; $breadcrumb = array();}
|
||||
|
||||
while($i < count($searchArray))
|
||||
{
|
||||
$item = $content[$searchArray[$i]];
|
||||
|
||||
if($i == count($searchArray)-1)
|
||||
{
|
||||
$item->active = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$item->activeParent = true;
|
||||
}
|
||||
/*
|
||||
$item->active = true;
|
||||
if($i == count($searchArray)-2)
|
||||
{
|
||||
$item->activeParent = true;
|
||||
}
|
||||
*/
|
||||
|
||||
$copy = clone($item);
|
||||
if($copy->elementType == 'folder')
|
||||
{
|
||||
unset($copy->folderContent);
|
||||
$content = $item->folderContent;
|
||||
}
|
||||
$breadcrumb[] = $copy;
|
||||
|
||||
$i++;
|
||||
return self::getBreadcrumb($content, $searchArray, $i++, $breadcrumb);
|
||||
}
|
||||
return $breadcrumb;
|
||||
}
|
||||
|
||||
public static function getParentItem($content, $searchArray, $iteration = NULL)
|
||||
{
|
||||
if(!$iteration){ $iteration = 0; }
|
||||
while($iteration < count($searchArray)-2)
|
||||
{
|
||||
$content = $content[$searchArray[$iteration]]->folderContent;
|
||||
$iteration++;
|
||||
return self::getParentItem($content, $searchArray, $iteration);
|
||||
}
|
||||
return $content[$searchArray[$iteration]];
|
||||
}
|
||||
|
||||
private static function getLastItemOfFolder($folder)
|
||||
{
|
||||
$lastItem = end($folder->folderContent);
|
||||
if(is_object($lastItem) && $lastItem->elementType == 'folder' && !empty($lastItem->folderContent))
|
||||
{
|
||||
return self::getLastItemOfFolder($lastItem);
|
||||
}
|
||||
return $lastItem;
|
||||
}
|
||||
|
||||
public static function getStringParts($name)
|
||||
{
|
||||
return preg_split('/[\-\.\_\=\+\?\!\*\#\(\)\/ ]/',$name);
|
||||
}
|
||||
|
||||
public static function getFileType($fileName)
|
||||
{
|
||||
$parts = preg_split('/\./',$fileName);
|
||||
return end($parts);
|
||||
}
|
||||
|
||||
public static function splitFileName($fileName)
|
||||
{
|
||||
$parts = preg_split('/\./',$fileName);
|
||||
return $parts;
|
||||
}
|
||||
}
|
@@ -1,28 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
class Helpers{
|
||||
|
||||
public static function printTimer($timer)
|
||||
{
|
||||
$lastTime = NULL;
|
||||
$table = '<html><body><table>';
|
||||
$table .= '<tr><th>Breakpoint</th><th>Time</th><th>Duration</th></tr>';
|
||||
foreach($timer as $breakpoint => $time)
|
||||
{
|
||||
$duration = $time - $lastTime;
|
||||
|
||||
$table .= '<tr>';
|
||||
$table .= '<td>' . $breakpoint . '</td>';
|
||||
$table .= '<td>' . $time . '</td>';
|
||||
$table .= '<td>' . $duration . '</td>';
|
||||
$table .= '</tr>';
|
||||
|
||||
$lastTime = $time;
|
||||
}
|
||||
$table .= '</table></body></html>';
|
||||
echo $table;
|
||||
exit;
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
class Helpers{
|
||||
|
||||
public static function printTimer($timer)
|
||||
{
|
||||
$lastTime = NULL;
|
||||
$table = '<html><body><table>';
|
||||
$table .= '<tr><th>Breakpoint</th><th>Time</th><th>Duration</th></tr>';
|
||||
foreach($timer as $breakpoint => $time)
|
||||
{
|
||||
$duration = $time - $lastTime;
|
||||
|
||||
$table .= '<tr>';
|
||||
$table .= '<td>' . $breakpoint . '</td>';
|
||||
$table .= '<td>' . $time . '</td>';
|
||||
$table .= '<td>' . $duration . '</td>';
|
||||
$table .= '</tr>';
|
||||
|
||||
$lastTime = $time;
|
||||
}
|
||||
$table .= '</table></body></html>';
|
||||
echo $table;
|
||||
exit;
|
||||
}
|
||||
}
|
@@ -1,336 +1,336 @@
|
||||
<?php
|
||||
namespace Typemill\Models;
|
||||
|
||||
class ProcessImage
|
||||
{
|
||||
public function createImage(string $image, array $desiredSizes)
|
||||
{
|
||||
# fix error from jpeg-library
|
||||
ini_set ('gd.jpeg_ignore_warning', 1);
|
||||
error_reporting(E_ALL & ~E_NOTICE);
|
||||
|
||||
# clear temporary folder
|
||||
$this->clearTempFolder();
|
||||
|
||||
# decode the image from base64-string
|
||||
$imageDecoded = $this->decodeImage($image);
|
||||
$imageData = $imageDecoded["image"];
|
||||
$imageType = $imageDecoded["type"];
|
||||
|
||||
# transform image-stream into image
|
||||
$image = imagecreatefromstring($imageData);
|
||||
|
||||
# get the size of the original image
|
||||
$imageSize = $this->getImageSize($image);
|
||||
|
||||
# check the desired sizes and calculate the height, if not set
|
||||
$desiredSizes = $this->setHeight($imageSize, $desiredSizes);
|
||||
|
||||
# resize the images
|
||||
$resizedImages = $this->imageResize($image, $imageSize, $desiredSizes, $imageType);
|
||||
|
||||
$basePath = getcwd() . DIRECTORY_SEPARATOR . 'media';
|
||||
$tmpFolder = $basePath . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR;
|
||||
|
||||
$this->saveOriginal($tmpFolder, $imageData, 'original', $imageType);
|
||||
|
||||
if($imageType == "gif" && $this->detectAnimatedGif($imageData))
|
||||
{
|
||||
$this->saveOriginal($tmpFolder, $imageData, 'live', $imageType);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
# temporary store resized images
|
||||
foreach($resizedImages as $key => $resizedImage)
|
||||
{
|
||||
$this->saveImage($tmpFolder, $resizedImage, $key, $imageType);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function detectAnimatedGif($image_file_contents)
|
||||
{
|
||||
$is_animated = preg_match('#(\x00\x21\xF9\x04.{4}\x00\x2C.*){2,}#s', $image_file_contents);
|
||||
if ($is_animated == 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function publishImage(array $desiredSizes, $name = false)
|
||||
{
|
||||
/* get images from tmp folder */
|
||||
$basePath = getcwd() . DIRECTORY_SEPARATOR . 'media';
|
||||
$tmpFolder = $basePath . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR;
|
||||
$originalFolder = $basePath . DIRECTORY_SEPARATOR . 'original' . DIRECTORY_SEPARATOR;
|
||||
$liveFolder = $basePath . DIRECTORY_SEPARATOR . 'live' . DIRECTORY_SEPARATOR;
|
||||
|
||||
if(!file_exists($originalFolder)){ mkdir($originalFolder, 0774, true); }
|
||||
if(!file_exists($liveFolder)){ mkdir($liveFolder, 0774, true); }
|
||||
|
||||
$name = $name ? $name : uniqid();
|
||||
|
||||
$files = scandir($tmpFolder);
|
||||
$success = true;
|
||||
|
||||
foreach($files as $file)
|
||||
{
|
||||
if (!in_array($file, array(".","..")))
|
||||
{
|
||||
$tmpfilename = explode(".", $file);
|
||||
|
||||
if($tmpfilename[0] == 'original')
|
||||
{
|
||||
$success = rename($tmpFolder . $file, $originalFolder . $name . '-' . $file);
|
||||
}
|
||||
else
|
||||
{
|
||||
$success = rename($tmpFolder . $file, $liveFolder . $name . '-' . $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($success)
|
||||
{
|
||||
return 'media/live/' . $name . '-live.' . $tmpfilename[1];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function decodeImage(string $image)
|
||||
{
|
||||
$imageParts = explode(";base64,", $image);
|
||||
$imageType = explode("/", $imageParts[0]);
|
||||
$imageData = base64_decode($imageParts[1]);
|
||||
|
||||
if ($imageData !== false)
|
||||
{
|
||||
return array("image" => $imageData, "type" => $imageType[1]);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getImageSize($image)
|
||||
{
|
||||
$width = imagesx($image);
|
||||
$height = imagesy($image);
|
||||
return array('width' => $width, 'height' => $height);
|
||||
}
|
||||
|
||||
public function setHeight(array $imageSize, array $desiredSizes)
|
||||
{
|
||||
foreach($desiredSizes as $key => $desiredSize)
|
||||
{
|
||||
if($desiredSize['width'] > $imageSize['width'])
|
||||
{
|
||||
$desiredSizes[$key] = $imageSize;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!isset($desiredSize['height']))
|
||||
{
|
||||
$resizeFactor = $imageSize['width'] / $desiredSize['width'];
|
||||
$desiredSizes[$key]['height'] = round( ($imageSize['height'] / $resizeFactor), 0);
|
||||
}
|
||||
}
|
||||
return $desiredSizes;
|
||||
}
|
||||
|
||||
public function imageResize($imageData, array $imageSize, array $desiredSizes, $imageType)
|
||||
{
|
||||
$copiedImages = array();
|
||||
$source_aspect_ratio = $imageSize['width'] / $imageSize['height'];
|
||||
|
||||
foreach($desiredSizes as $key => $desiredSize)
|
||||
{
|
||||
$desired_aspect_ratio = $desiredSize['width'] / $desiredSize['height'];
|
||||
|
||||
if ( $source_aspect_ratio > $desired_aspect_ratio )
|
||||
{
|
||||
# when source image is wider
|
||||
$temp_height = $desiredSize['height'];
|
||||
$temp_width = ( int ) ($desiredSize['height'] * $source_aspect_ratio);
|
||||
$temp_width = round($temp_width, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
# when source image is similar or taller
|
||||
$temp_width = $desiredSize['width'];
|
||||
$temp_height = ( int ) ($desiredSize['width'] / $source_aspect_ratio);
|
||||
$temp_height = round($temp_height, 0);
|
||||
}
|
||||
|
||||
# Create a temporary GD image with desired size
|
||||
$temp_gdim = imagecreatetruecolor( $temp_width, $temp_height );
|
||||
|
||||
if ($imageType == "gif")
|
||||
{
|
||||
$transparent_index = imagecolortransparent($imageData);
|
||||
imagepalettecopy($imageData, $temp_gdim);
|
||||
imagefill($temp_gdim, 0, 0, $transparent_index);
|
||||
imagecolortransparent($temp_gdim, $transparent_index);
|
||||
imagetruecolortopalette($temp_gdim, true, 256);
|
||||
}
|
||||
elseif($imageType == "png")
|
||||
{
|
||||
imagealphablending($temp_gdim, false);
|
||||
imagesavealpha($temp_gdim, true);
|
||||
$transparent = imagecolorallocatealpha($temp_gdim, 255, 255, 255, 127);
|
||||
imagefilledrectangle($temp_gdim, 0, 0, $temp_width, $temp_height, $transparent);
|
||||
}
|
||||
|
||||
# resize image
|
||||
imagecopyresampled(
|
||||
$temp_gdim,
|
||||
$imageData,
|
||||
0, 0,
|
||||
0, 0,
|
||||
$temp_width, $temp_height,
|
||||
$imageSize['width'], $imageSize['height']
|
||||
);
|
||||
|
||||
$copiedImages[$key] = $temp_gdim;
|
||||
|
||||
/*
|
||||
|
||||
# Copy cropped region from temporary image into the desired GD image
|
||||
$x0 = ( $temp_width - $desiredSize['width'] ) / 2;
|
||||
$y0 = ( $temp_height - $desiredSize['height'] ) / 2;
|
||||
|
||||
$desired_gdim = imagecreatetruecolor( $desiredSize['width'], $desiredSize['height'] );
|
||||
|
||||
if ($imageType == "gif")
|
||||
{
|
||||
imagepalettecopy($temp_gdim, $desired_gdim);
|
||||
imagefill($desired_gdim, 0, 0, $transparent_index);
|
||||
imagecolortransparent($desired_gdim, $transparent_index);
|
||||
imagetruecolortopalette($desired_gdim, true, 256);
|
||||
}
|
||||
elseif($imageType == "png")
|
||||
{
|
||||
imagealphablending($desired_gdim, false);
|
||||
imagesavealpha($desired_gdim,true);
|
||||
$transparent = imagecolorallocatealpha($desired_gdim, 255, 255, 255, 127);
|
||||
imagefilledrectangle($desired_gdim, 0, 0, $desired_size['with'], $desired_size['height'], $transparent);
|
||||
}
|
||||
|
||||
imagecopyresampled(
|
||||
$desired_gdim,
|
||||
$temp_gdim,
|
||||
0, 0,
|
||||
0, 0,
|
||||
$x0, $y0,
|
||||
$desiredSize['width'], $desiredSize['height']
|
||||
);
|
||||
$copiedImages[$key] = $desired_gdim;
|
||||
|
||||
*/
|
||||
}
|
||||
return $copiedImages;
|
||||
}
|
||||
|
||||
public function saveOriginal($folder, $image, $name, $type)
|
||||
{
|
||||
if(!file_exists($folder))
|
||||
{
|
||||
mkdir($folder, 0774, true);
|
||||
}
|
||||
|
||||
$path = $folder . $name . '.' . $type;
|
||||
|
||||
file_put_contents($path, $image);
|
||||
}
|
||||
|
||||
public function saveImage($folder, $image, $name, $type)
|
||||
{
|
||||
if(!file_exists($folder))
|
||||
{
|
||||
mkdir($folder, 0774, true);
|
||||
}
|
||||
|
||||
if($type == "png")
|
||||
{
|
||||
$result = imagepng( $image, $folder . '/' . $name . '.png' );
|
||||
}
|
||||
elseif($type == "gif")
|
||||
{
|
||||
$result = imagegif( $image, $folder . '/' . $name . '.gif' );
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = imagejpeg( $image, $folder . '/' . $name . '.jpeg' );
|
||||
$type = 'jpeg';
|
||||
}
|
||||
|
||||
imagedestroy($image);
|
||||
|
||||
if($result)
|
||||
{
|
||||
return $name . '.' . $type;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function clearTempFolder()
|
||||
{
|
||||
$folder = getcwd() . DIRECTORY_SEPARATOR . 'media' . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR;
|
||||
|
||||
if(!file_exists($folder))
|
||||
{
|
||||
mkdir($folder, 0774, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
$files = scandir($folder);
|
||||
$result = true;
|
||||
|
||||
foreach($files as $file)
|
||||
{
|
||||
if (!in_array($file, array(".","..")))
|
||||
{
|
||||
$filelink = $folder . $file;
|
||||
if(!unlink($filelink))
|
||||
{
|
||||
$success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function deleteImage($name)
|
||||
{
|
||||
$baseFolder = getcwd() . DIRECTORY_SEPARATOR . 'media' . DIRECTORY_SEPARATOR;
|
||||
$original = $baseFolder . 'original' . DIRECTORY_SEPARATOR . $name . '*';
|
||||
$live = $baseFolder . 'live' . DIRECTORY_SEPARATOR . $name . '*';
|
||||
$success = true;
|
||||
|
||||
foreach(glob($original) as $image)
|
||||
{
|
||||
if(!unlink($image))
|
||||
{
|
||||
$success = false;
|
||||
}
|
||||
}
|
||||
|
||||
foreach(glob($live) as $image)
|
||||
{
|
||||
if(!unlink($image))
|
||||
{
|
||||
$success = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
<?php
|
||||
namespace Typemill\Models;
|
||||
|
||||
class ProcessImage
|
||||
{
|
||||
public function createImage(string $image, array $desiredSizes)
|
||||
{
|
||||
# fix error from jpeg-library
|
||||
ini_set ('gd.jpeg_ignore_warning', 1);
|
||||
error_reporting(E_ALL & ~E_NOTICE);
|
||||
|
||||
# clear temporary folder
|
||||
$this->clearTempFolder();
|
||||
|
||||
# decode the image from base64-string
|
||||
$imageDecoded = $this->decodeImage($image);
|
||||
$imageData = $imageDecoded["image"];
|
||||
$imageType = $imageDecoded["type"];
|
||||
|
||||
# transform image-stream into image
|
||||
$image = imagecreatefromstring($imageData);
|
||||
|
||||
# get the size of the original image
|
||||
$imageSize = $this->getImageSize($image);
|
||||
|
||||
# check the desired sizes and calculate the height, if not set
|
||||
$desiredSizes = $this->setHeight($imageSize, $desiredSizes);
|
||||
|
||||
# resize the images
|
||||
$resizedImages = $this->imageResize($image, $imageSize, $desiredSizes, $imageType);
|
||||
|
||||
$basePath = getcwd() . DIRECTORY_SEPARATOR . 'media';
|
||||
$tmpFolder = $basePath . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR;
|
||||
|
||||
$this->saveOriginal($tmpFolder, $imageData, 'original', $imageType);
|
||||
|
||||
if($imageType == "gif" && $this->detectAnimatedGif($imageData))
|
||||
{
|
||||
$this->saveOriginal($tmpFolder, $imageData, 'live', $imageType);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
# temporary store resized images
|
||||
foreach($resizedImages as $key => $resizedImage)
|
||||
{
|
||||
$this->saveImage($tmpFolder, $resizedImage, $key, $imageType);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function detectAnimatedGif($image_file_contents)
|
||||
{
|
||||
$is_animated = preg_match('#(\x00\x21\xF9\x04.{4}\x00\x2C.*){2,}#s', $image_file_contents);
|
||||
if ($is_animated == 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function publishImage(array $desiredSizes, $name = false)
|
||||
{
|
||||
/* get images from tmp folder */
|
||||
$basePath = getcwd() . DIRECTORY_SEPARATOR . 'media';
|
||||
$tmpFolder = $basePath . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR;
|
||||
$originalFolder = $basePath . DIRECTORY_SEPARATOR . 'original' . DIRECTORY_SEPARATOR;
|
||||
$liveFolder = $basePath . DIRECTORY_SEPARATOR . 'live' . DIRECTORY_SEPARATOR;
|
||||
|
||||
if(!file_exists($originalFolder)){ mkdir($originalFolder, 0774, true); }
|
||||
if(!file_exists($liveFolder)){ mkdir($liveFolder, 0774, true); }
|
||||
|
||||
$name = $name ? $name : uniqid();
|
||||
|
||||
$files = scandir($tmpFolder);
|
||||
$success = true;
|
||||
|
||||
foreach($files as $file)
|
||||
{
|
||||
if (!in_array($file, array(".","..")))
|
||||
{
|
||||
$tmpfilename = explode(".", $file);
|
||||
|
||||
if($tmpfilename[0] == 'original')
|
||||
{
|
||||
$success = rename($tmpFolder . $file, $originalFolder . $name . '-' . $file);
|
||||
}
|
||||
else
|
||||
{
|
||||
$success = rename($tmpFolder . $file, $liveFolder . $name . '-' . $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($success)
|
||||
{
|
||||
return 'media/live/' . $name . '-live.' . $tmpfilename[1];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function decodeImage(string $image)
|
||||
{
|
||||
$imageParts = explode(";base64,", $image);
|
||||
$imageType = explode("/", $imageParts[0]);
|
||||
$imageData = base64_decode($imageParts[1]);
|
||||
|
||||
if ($imageData !== false)
|
||||
{
|
||||
return array("image" => $imageData, "type" => $imageType[1]);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getImageSize($image)
|
||||
{
|
||||
$width = imagesx($image);
|
||||
$height = imagesy($image);
|
||||
return array('width' => $width, 'height' => $height);
|
||||
}
|
||||
|
||||
public function setHeight(array $imageSize, array $desiredSizes)
|
||||
{
|
||||
foreach($desiredSizes as $key => $desiredSize)
|
||||
{
|
||||
if($desiredSize['width'] > $imageSize['width'])
|
||||
{
|
||||
$desiredSizes[$key] = $imageSize;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!isset($desiredSize['height']))
|
||||
{
|
||||
$resizeFactor = $imageSize['width'] / $desiredSize['width'];
|
||||
$desiredSizes[$key]['height'] = round( ($imageSize['height'] / $resizeFactor), 0);
|
||||
}
|
||||
}
|
||||
return $desiredSizes;
|
||||
}
|
||||
|
||||
public function imageResize($imageData, array $imageSize, array $desiredSizes, $imageType)
|
||||
{
|
||||
$copiedImages = array();
|
||||
$source_aspect_ratio = $imageSize['width'] / $imageSize['height'];
|
||||
|
||||
foreach($desiredSizes as $key => $desiredSize)
|
||||
{
|
||||
$desired_aspect_ratio = $desiredSize['width'] / $desiredSize['height'];
|
||||
|
||||
if ( $source_aspect_ratio > $desired_aspect_ratio )
|
||||
{
|
||||
# when source image is wider
|
||||
$temp_height = $desiredSize['height'];
|
||||
$temp_width = ( int ) ($desiredSize['height'] * $source_aspect_ratio);
|
||||
$temp_width = round($temp_width, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
# when source image is similar or taller
|
||||
$temp_width = $desiredSize['width'];
|
||||
$temp_height = ( int ) ($desiredSize['width'] / $source_aspect_ratio);
|
||||
$temp_height = round($temp_height, 0);
|
||||
}
|
||||
|
||||
# Create a temporary GD image with desired size
|
||||
$temp_gdim = imagecreatetruecolor( $temp_width, $temp_height );
|
||||
|
||||
if ($imageType == "gif")
|
||||
{
|
||||
$transparent_index = imagecolortransparent($imageData);
|
||||
imagepalettecopy($imageData, $temp_gdim);
|
||||
imagefill($temp_gdim, 0, 0, $transparent_index);
|
||||
imagecolortransparent($temp_gdim, $transparent_index);
|
||||
imagetruecolortopalette($temp_gdim, true, 256);
|
||||
}
|
||||
elseif($imageType == "png")
|
||||
{
|
||||
imagealphablending($temp_gdim, false);
|
||||
imagesavealpha($temp_gdim, true);
|
||||
$transparent = imagecolorallocatealpha($temp_gdim, 255, 255, 255, 127);
|
||||
imagefilledrectangle($temp_gdim, 0, 0, $temp_width, $temp_height, $transparent);
|
||||
}
|
||||
|
||||
# resize image
|
||||
imagecopyresampled(
|
||||
$temp_gdim,
|
||||
$imageData,
|
||||
0, 0,
|
||||
0, 0,
|
||||
$temp_width, $temp_height,
|
||||
$imageSize['width'], $imageSize['height']
|
||||
);
|
||||
|
||||
$copiedImages[$key] = $temp_gdim;
|
||||
|
||||
/*
|
||||
|
||||
# Copy cropped region from temporary image into the desired GD image
|
||||
$x0 = ( $temp_width - $desiredSize['width'] ) / 2;
|
||||
$y0 = ( $temp_height - $desiredSize['height'] ) / 2;
|
||||
|
||||
$desired_gdim = imagecreatetruecolor( $desiredSize['width'], $desiredSize['height'] );
|
||||
|
||||
if ($imageType == "gif")
|
||||
{
|
||||
imagepalettecopy($temp_gdim, $desired_gdim);
|
||||
imagefill($desired_gdim, 0, 0, $transparent_index);
|
||||
imagecolortransparent($desired_gdim, $transparent_index);
|
||||
imagetruecolortopalette($desired_gdim, true, 256);
|
||||
}
|
||||
elseif($imageType == "png")
|
||||
{
|
||||
imagealphablending($desired_gdim, false);
|
||||
imagesavealpha($desired_gdim,true);
|
||||
$transparent = imagecolorallocatealpha($desired_gdim, 255, 255, 255, 127);
|
||||
imagefilledrectangle($desired_gdim, 0, 0, $desired_size['with'], $desired_size['height'], $transparent);
|
||||
}
|
||||
|
||||
imagecopyresampled(
|
||||
$desired_gdim,
|
||||
$temp_gdim,
|
||||
0, 0,
|
||||
0, 0,
|
||||
$x0, $y0,
|
||||
$desiredSize['width'], $desiredSize['height']
|
||||
);
|
||||
$copiedImages[$key] = $desired_gdim;
|
||||
|
||||
*/
|
||||
}
|
||||
return $copiedImages;
|
||||
}
|
||||
|
||||
public function saveOriginal($folder, $image, $name, $type)
|
||||
{
|
||||
if(!file_exists($folder))
|
||||
{
|
||||
mkdir($folder, 0774, true);
|
||||
}
|
||||
|
||||
$path = $folder . $name . '.' . $type;
|
||||
|
||||
file_put_contents($path, $image);
|
||||
}
|
||||
|
||||
public function saveImage($folder, $image, $name, $type)
|
||||
{
|
||||
if(!file_exists($folder))
|
||||
{
|
||||
mkdir($folder, 0774, true);
|
||||
}
|
||||
|
||||
if($type == "png")
|
||||
{
|
||||
$result = imagepng( $image, $folder . '/' . $name . '.png' );
|
||||
}
|
||||
elseif($type == "gif")
|
||||
{
|
||||
$result = imagegif( $image, $folder . '/' . $name . '.gif' );
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = imagejpeg( $image, $folder . '/' . $name . '.jpeg' );
|
||||
$type = 'jpeg';
|
||||
}
|
||||
|
||||
imagedestroy($image);
|
||||
|
||||
if($result)
|
||||
{
|
||||
return $name . '.' . $type;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function clearTempFolder()
|
||||
{
|
||||
$folder = getcwd() . DIRECTORY_SEPARATOR . 'media' . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR;
|
||||
|
||||
if(!file_exists($folder))
|
||||
{
|
||||
mkdir($folder, 0774, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
$files = scandir($folder);
|
||||
$result = true;
|
||||
|
||||
foreach($files as $file)
|
||||
{
|
||||
if (!in_array($file, array(".","..")))
|
||||
{
|
||||
$filelink = $folder . $file;
|
||||
if(!unlink($filelink))
|
||||
{
|
||||
$success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function deleteImage($name)
|
||||
{
|
||||
$baseFolder = getcwd() . DIRECTORY_SEPARATOR . 'media' . DIRECTORY_SEPARATOR;
|
||||
$original = $baseFolder . 'original' . DIRECTORY_SEPARATOR . $name . '*';
|
||||
$live = $baseFolder . 'live' . DIRECTORY_SEPARATOR . $name . '*';
|
||||
$success = true;
|
||||
|
||||
foreach(glob($original) as $image)
|
||||
{
|
||||
if(!unlink($image))
|
||||
{
|
||||
$success = false;
|
||||
}
|
||||
}
|
||||
|
||||
foreach(glob($live) as $image)
|
||||
{
|
||||
if(!unlink($image))
|
||||
{
|
||||
$success = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
@@ -1,98 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
class User extends WriteYaml
|
||||
{
|
||||
public function getUsers()
|
||||
{
|
||||
$userDir = __DIR__ . '/../../settings/users';
|
||||
|
||||
/* check if plugins directory exists */
|
||||
if(!is_dir($userDir)){ return array(); }
|
||||
|
||||
/* get all plugins folder */
|
||||
$users = array_diff(scandir($userDir), array('..', '.'));
|
||||
|
||||
$cleanUser = array();
|
||||
foreach($users as $key => $user)
|
||||
{
|
||||
if($user == '.logins'){ continue; }
|
||||
$cleanUser[] = str_replace('.yaml', '', $user);
|
||||
}
|
||||
|
||||
return $cleanUser;
|
||||
}
|
||||
|
||||
public function getUser($username)
|
||||
{
|
||||
$user = $this->getYaml('settings/users', $username . '.yaml');
|
||||
return $user;
|
||||
}
|
||||
|
||||
public function createUser($params)
|
||||
{
|
||||
$userdata = array(
|
||||
'username' => $params['username'],
|
||||
'email' => $params['email'],
|
||||
'password' => $this->generatePassword($params['password']),
|
||||
'userrole' => $params['userrole']
|
||||
);
|
||||
|
||||
if($this->updateYaml('settings/users', $userdata['username'] . '.yaml', $userdata))
|
||||
{
|
||||
return $userdata['username'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function updateUser($params)
|
||||
{
|
||||
$userdata = $this->getUser($params['username']);
|
||||
|
||||
if(isset($params['password']))
|
||||
{
|
||||
$params['password'] = $this->generatePassword($params['password']);
|
||||
}
|
||||
|
||||
$update = array_merge($userdata, $params);
|
||||
|
||||
$this->updateYaml('settings/users', $userdata['username'] . '.yaml', $update);
|
||||
|
||||
return $userdata['username'];
|
||||
}
|
||||
|
||||
public function deleteUser($username)
|
||||
{
|
||||
if($this->getUser($username))
|
||||
{
|
||||
unlink('settings/users/' . $username . '.yaml');
|
||||
}
|
||||
}
|
||||
|
||||
public function getUserroles()
|
||||
{
|
||||
return array('administrator', 'editor');
|
||||
}
|
||||
|
||||
public function login($username)
|
||||
{
|
||||
$user = $this->getUser($username);
|
||||
|
||||
if($user)
|
||||
{
|
||||
$user['lastlogin'] = time();
|
||||
unset($user['password']);
|
||||
$this->updateUser($user);
|
||||
|
||||
$_SESSION['user'] = $user['username'];
|
||||
$_SESSION['role'] = $user['userrole'];
|
||||
$_SESSION['login'] = $user['lastlogin'];
|
||||
}
|
||||
}
|
||||
|
||||
public function generatePassword($password)
|
||||
{
|
||||
return \password_hash($password, PASSWORD_DEFAULT, ['cost' => 10]);
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
class User extends WriteYaml
|
||||
{
|
||||
public function getUsers()
|
||||
{
|
||||
$userDir = __DIR__ . '/../../settings/users';
|
||||
|
||||
/* check if plugins directory exists */
|
||||
if(!is_dir($userDir)){ return array(); }
|
||||
|
||||
/* get all plugins folder */
|
||||
$users = array_diff(scandir($userDir), array('..', '.'));
|
||||
|
||||
$cleanUser = array();
|
||||
foreach($users as $key => $user)
|
||||
{
|
||||
if($user == '.logins'){ continue; }
|
||||
$cleanUser[] = str_replace('.yaml', '', $user);
|
||||
}
|
||||
|
||||
return $cleanUser;
|
||||
}
|
||||
|
||||
public function getUser($username)
|
||||
{
|
||||
$user = $this->getYaml('settings/users', $username . '.yaml');
|
||||
return $user;
|
||||
}
|
||||
|
||||
public function createUser($params)
|
||||
{
|
||||
$userdata = array(
|
||||
'username' => $params['username'],
|
||||
'email' => $params['email'],
|
||||
'password' => $this->generatePassword($params['password']),
|
||||
'userrole' => $params['userrole']
|
||||
);
|
||||
|
||||
if($this->updateYaml('settings/users', $userdata['username'] . '.yaml', $userdata))
|
||||
{
|
||||
return $userdata['username'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function updateUser($params)
|
||||
{
|
||||
$userdata = $this->getUser($params['username']);
|
||||
|
||||
if(isset($params['password']))
|
||||
{
|
||||
$params['password'] = $this->generatePassword($params['password']);
|
||||
}
|
||||
|
||||
$update = array_merge($userdata, $params);
|
||||
|
||||
$this->updateYaml('settings/users', $userdata['username'] . '.yaml', $update);
|
||||
|
||||
return $userdata['username'];
|
||||
}
|
||||
|
||||
public function deleteUser($username)
|
||||
{
|
||||
if($this->getUser($username))
|
||||
{
|
||||
unlink('settings/users/' . $username . '.yaml');
|
||||
}
|
||||
}
|
||||
|
||||
public function getUserroles()
|
||||
{
|
||||
return array('administrator', 'editor');
|
||||
}
|
||||
|
||||
public function login($username)
|
||||
{
|
||||
$user = $this->getUser($username);
|
||||
|
||||
if($user)
|
||||
{
|
||||
$user['lastlogin'] = time();
|
||||
unset($user['password']);
|
||||
$this->updateUser($user);
|
||||
|
||||
$_SESSION['user'] = $user['username'];
|
||||
$_SESSION['role'] = $user['userrole'];
|
||||
$_SESSION['login'] = $user['lastlogin'];
|
||||
}
|
||||
}
|
||||
|
||||
public function generatePassword($password)
|
||||
{
|
||||
return \password_hash($password, PASSWORD_DEFAULT, ['cost' => 10]);
|
||||
}
|
||||
}
|
@@ -1,418 +1,418 @@
|
||||
<?php
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
use Typemill\Models\User;
|
||||
use Valitron\Validator;
|
||||
|
||||
class Validation
|
||||
{
|
||||
/**
|
||||
* Constructor with custom validation rules
|
||||
*
|
||||
* @param obj $db the database connection.
|
||||
*/
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$user = new User();
|
||||
|
||||
Validator::langDir(__DIR__.'/../vendor/vlucas/valitron/lang'); // always set langDir before lang.
|
||||
Validator::lang('en');
|
||||
|
||||
Validator::addRule('userAvailable', function($field, $value, array $params, array $fields) use ($user)
|
||||
{
|
||||
$userdata = $user->getUser($value);
|
||||
if($userdata){ return false; }
|
||||
return true;
|
||||
}, 'taken');
|
||||
|
||||
Validator::addRule('userExists', function($field, $value, array $params, array $fields) use ($user)
|
||||
{
|
||||
$userdata = $user->getUser($value);
|
||||
if($userdata){ return true; }
|
||||
return false;
|
||||
}, 'does not exist');
|
||||
|
||||
Validator::addRule('checkPassword', function($field, $value, array $params, array $fields) use ($user)
|
||||
{
|
||||
$userdata = $user->getUser($fields['username']);
|
||||
if($userdata && password_verify($value, $userdata['password'])){ return true; }
|
||||
return false;
|
||||
}, 'wrong password');
|
||||
|
||||
Validator::addRule('emailAvailable', function($field, $value, array $params, array $fields)
|
||||
{
|
||||
$email = 'testmail@gmail.com';
|
||||
if($email){ return false; }
|
||||
return true;
|
||||
}, 'taken');
|
||||
|
||||
Validator::addRule('emailKnown', function($field, $value, array $params, array $fields)
|
||||
{
|
||||
$email = 'testmail@gmail.com';
|
||||
if(!$email){ return false; }
|
||||
return true;
|
||||
}, 'unknown');
|
||||
|
||||
Validator::addRule('noSpecialChars', function($field, $value, array $params, array $fields)
|
||||
{
|
||||
$format = '/[!@#$%^&*()_+=\[\]{};\':"\\|,.<>\/?]/';
|
||||
if ( preg_match($format, $value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}, 'contains special characters');
|
||||
|
||||
Validator::addRule('noHTML', function($field, $value, array $params, array $fields)
|
||||
{
|
||||
if ( $value == strip_tags($value) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}, 'contains html');
|
||||
|
||||
Validator::addRule('markdownSecure', function($field, $value, array $params, array $fields)
|
||||
{
|
||||
/* strip out code blocks and blockquotes */
|
||||
$value = preg_replace('/`{4,}[\s\S]+?`{4,}/', '', $value);
|
||||
$value = preg_replace('/`{3,}[\s\S]+?`{3,}/', '', $value);
|
||||
$value = preg_replace('/`{2,}[\s\S]+?`{2,}/', '', $value);
|
||||
$value = preg_replace('/`{1,}[\s\S]+?`{1,}/', '', $value);
|
||||
$value = preg_replace('/>[\s\S]+?[\n\r]/', '', $value);
|
||||
|
||||
if ( $value == strip_tags($value) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}, 'not secure. For code please use markdown `inline-code` or ````fenced code blocks````.');
|
||||
}
|
||||
|
||||
/**
|
||||
* validation for signup form
|
||||
*
|
||||
* @param array $params with form data.
|
||||
* @return obj $v the validation object passed to a result method.
|
||||
*/
|
||||
|
||||
public function signin(array $params)
|
||||
{
|
||||
$v = new Validator($params);
|
||||
$v->rule('required', ['username', 'password'])->message("Required");
|
||||
$v->rule('alphaNum', 'username')->message("Invalid characters");
|
||||
$v->rule('lengthBetween', 'password', 5, 20)->message("Length between 5 - 20");
|
||||
$v->rule('lengthBetween', 'username', 3, 20)->message("Length between 3 - 20");
|
||||
|
||||
if($v->validate())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* validation for signup form
|
||||
*
|
||||
* @param array $params with form data.
|
||||
* @return obj $v the validation object passed to a result method.
|
||||
*/
|
||||
|
||||
public function newUser(array $params, $userroles)
|
||||
{
|
||||
$v = new Validator($params);
|
||||
$v->rule('required', ['username', 'email', 'password'])->message("required");
|
||||
$v->rule('alphaNum', 'username')->message("invalid characters");
|
||||
$v->rule('lengthBetween', 'password', 5, 20)->message("Length between 5 - 20");
|
||||
$v->rule('lengthBetween', 'username', 3, 20)->message("Length between 3 - 20");
|
||||
$v->rule('userAvailable', 'username')->message("User already exists");
|
||||
$v->rule('email', 'email')->message("e-mail is invalid");
|
||||
$v->rule('in', 'userrole', $userroles);
|
||||
|
||||
return $this->validationResult($v);
|
||||
}
|
||||
|
||||
public function existingUser(array $params, $userroles)
|
||||
{
|
||||
$v = new Validator($params);
|
||||
$v->rule('required', ['username', 'email', 'userrole'])->message("required");
|
||||
$v->rule('alphaNum', 'username')->message("invalid");
|
||||
$v->rule('lengthBetween', 'username', 3, 20)->message("Length between 3 - 20");
|
||||
$v->rule('userExists', 'username')->message("user does not exist");
|
||||
$v->rule('email', 'email')->message("e-mail is invalid");
|
||||
$v->rule('in', 'userrole', $userroles);
|
||||
|
||||
return $this->validationResult($v);
|
||||
}
|
||||
|
||||
public function username($username)
|
||||
{
|
||||
$v = new Validator($username);
|
||||
$v->rule('alphaNum', 'username')->message("Only alpha-numeric characters allowed");
|
||||
$v->rule('lengthBetween', 'username', 3, 20)->message("Length between 3 - 20");
|
||||
|
||||
return $this->validationResult($v);
|
||||
}
|
||||
|
||||
/**
|
||||
* validation for changing the password
|
||||
*
|
||||
* @param array $params with form data.
|
||||
* @return obj $v the validation object passed to a result method.
|
||||
*/
|
||||
|
||||
public function newPassword(array $params)
|
||||
{
|
||||
$v = new Validator($params);
|
||||
$v->rule('required', ['password', 'newpassword']);
|
||||
$v->rule('lengthBetween', 'newpassword', 5, 20);
|
||||
$v->rule('checkPassword', 'password')->message("Password is wrong");
|
||||
|
||||
return $this->validationResult($v);
|
||||
}
|
||||
|
||||
/**
|
||||
* validation for system settings
|
||||
*
|
||||
* @param array $params with form data.
|
||||
* @return obj $v the validation object passed to a result method.
|
||||
*/
|
||||
|
||||
public function settings(array $params, array $copyright, $name = false)
|
||||
{
|
||||
$v = new Validator($params);
|
||||
|
||||
$v->rule('required', ['title', 'author', 'copyright', 'year', 'editor']);
|
||||
$v->rule('lengthBetween', 'title', 2, 20);
|
||||
$v->rule('lengthBetween', 'author', 2, 40);
|
||||
$v->rule('regex', 'title', '/^[\pL0-9_ \-]*$/u');
|
||||
$v->rule('regex', 'author', '/^[\pL_ \-]*$/u');
|
||||
$v->rule('integer', 'year');
|
||||
$v->rule('length', 'year', 4);
|
||||
$v->rule('in', 'editor', ['raw', 'visual']);
|
||||
$v->rule('in', 'copyright', $copyright);
|
||||
|
||||
return $this->validationResult($v, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* validation for content editor
|
||||
*
|
||||
* @param array $params with form data.
|
||||
* @return true or $v->errors with array of errors to use in json-response
|
||||
*/
|
||||
|
||||
public function editorInput(array $params)
|
||||
{
|
||||
$v = new Validator($params);
|
||||
|
||||
$v->rule('required', ['title', 'content', 'url']);
|
||||
$v->rule('lengthBetween', 'title', 2, 100);
|
||||
$v->rule('noHTML', 'title');
|
||||
$v->rule('markdownSecure', 'content');
|
||||
|
||||
if($v->validate())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $v->errors();
|
||||
}
|
||||
}
|
||||
|
||||
public function blockInput(array $params)
|
||||
{
|
||||
$v = new Validator($params);
|
||||
|
||||
$v->rule('required', ['markdown', 'block_id', 'url']);
|
||||
$v->rule('markdownSecure', 'markdown');
|
||||
$v->rule('regex', 'block_id', '/^[0-9.]+$/i');
|
||||
|
||||
if($v->validate())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $v->errors();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* validation for resort navigation
|
||||
*
|
||||
* @param array $params with form data.
|
||||
* @return true or $v->errors with array of errors to use in json-response
|
||||
*/
|
||||
|
||||
public function navigationSort(array $params)
|
||||
{
|
||||
$v = new Validator($params);
|
||||
|
||||
$v->rule('required', ['item_id', 'parent_id_from', 'parent_id_to']);
|
||||
$v->rule('regex', 'item_id', '/^[0-9.]+$/i');
|
||||
$v->rule('regex', 'parent_id_from', '/^[a-zA-Z0-9.]+$/i');
|
||||
$v->rule('regex', 'parent_id_to', '/^[a-zA-Z0-9.]+$/i');
|
||||
$v->rule('integer', 'index_new');
|
||||
|
||||
if($v->validate())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $v->errors();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* validation for new navigation items
|
||||
*
|
||||
* @param array $params with form data.
|
||||
* @return true or $v->errors with array of errors to use in json-response
|
||||
*/
|
||||
|
||||
public function navigationItem(array $params)
|
||||
{
|
||||
$v = new Validator($params);
|
||||
|
||||
$v->rule('required', ['folder_id', 'item_name', 'type', 'url']);
|
||||
$v->rule('regex', 'folder_id', '/^[0-9.]+$/i');
|
||||
$v->rule('noSpecialChars', 'item_name');
|
||||
$v->rule('lengthBetween', 'item_name', 1, 40);
|
||||
$v->rule('in', 'type', ['file', 'folder']);
|
||||
|
||||
if($v->validate())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $v->errors();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* validation for dynamic fields ( settings for themes and plugins)
|
||||
*
|
||||
* @param string $fieldName with the name of the field.
|
||||
* @param array or string $fieldValue with the values of the field.
|
||||
* @param string $objectName with the name of the plugin or theme.
|
||||
* @param array $fieldDefinitions with the field definitions as multi-dimensional array.
|
||||
* @return obj $v the validation object passed to a result method.
|
||||
*/
|
||||
|
||||
public function objectField($fieldName, $fieldValue, $objectName, $fieldDefinitions)
|
||||
{
|
||||
$v = new Validator(array($fieldName => $fieldValue));
|
||||
|
||||
if(isset($fieldDefinitions['required']))
|
||||
{
|
||||
$v->rule('required', $fieldName);
|
||||
}
|
||||
|
||||
switch($fieldDefinitions['type'])
|
||||
{
|
||||
case "select":
|
||||
/* create array with option keys as value */
|
||||
$options = array();
|
||||
foreach($fieldDefinitions['options'] as $key => $value){ $options[] = $key; }
|
||||
$v->rule('in', $fieldName, $options);
|
||||
break;
|
||||
case "radio":
|
||||
$v->rule('in', $fieldName, $fieldDefinitions['options']);
|
||||
break;
|
||||
case "checkboxlist":
|
||||
/* create array with option keys as value */
|
||||
$options = array();
|
||||
foreach($fieldDefinitions['options'] as $key => $value){ $options[] = $key; }
|
||||
/* loop over input values and check, if the options of the field definitions (options for checkboxlist) contains the key (input from user, key is used as value, value is used as label) */
|
||||
foreach($fieldValue as $key => $value)
|
||||
{
|
||||
$v->rule('in', $key, $options);
|
||||
}
|
||||
break;
|
||||
case "color":
|
||||
$v->rule('regex', $fieldName, '/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/');
|
||||
break;
|
||||
case "email":
|
||||
$v->rule('email', $fieldName);
|
||||
break;
|
||||
case "date":
|
||||
$v->rule('date', $fieldName);
|
||||
break;
|
||||
case "checkbox":
|
||||
$v->rule('accepted', $fieldName);
|
||||
break;
|
||||
case "url":
|
||||
$v->rule('lengthMax', $fieldName, 200);
|
||||
$v->rule('url', $fieldName);
|
||||
break;
|
||||
case "text":
|
||||
$v->rule('lengthMax', $fieldName, 200);
|
||||
$v->rule('regex', $fieldName, '/^[\pL0-9_ \-\.\?\!\/\:]*$/u');
|
||||
break;
|
||||
case "textarea":
|
||||
$v->rule('lengthMax', $fieldName, 1000);
|
||||
$v->rule('noHTML', $fieldName);
|
||||
// $v->rule('regex', $fieldName, '/<[^<]+>/');
|
||||
break;
|
||||
case "paragraph":
|
||||
$v->rule('lengthMax', $fieldName, 1000);
|
||||
$v->rule('noHTML', $fieldName);
|
||||
break;
|
||||
case "password":
|
||||
$v->rule('lengthMax', $fieldName, 100);
|
||||
break;
|
||||
default:
|
||||
$v->rule('lengthMax', $fieldName, 1000);
|
||||
$v->rule('regex', $fieldName, '/^[\pL0-9_ \-]*$/u');
|
||||
}
|
||||
|
||||
return $this->validationResult($v, $objectName);
|
||||
}
|
||||
|
||||
/**
|
||||
* result for validation
|
||||
*
|
||||
* @param obj $v the validation object.
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
public function validationResult($v, $name = false)
|
||||
{
|
||||
if($v->validate())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if($name)
|
||||
{
|
||||
if(isset($_SESSION['errors'][$name]))
|
||||
{
|
||||
foreach ($v->errors() as $key => $val)
|
||||
{
|
||||
$_SESSION['errors'][$name][$key] = $val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$_SESSION['errors'][$name] = $v->errors();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$_SESSION['errors'] = $v->errors();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
use Typemill\Models\User;
|
||||
use Valitron\Validator;
|
||||
|
||||
class Validation
|
||||
{
|
||||
/**
|
||||
* Constructor with custom validation rules
|
||||
*
|
||||
* @param obj $db the database connection.
|
||||
*/
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$user = new User();
|
||||
|
||||
Validator::langDir(__DIR__.'/../vendor/vlucas/valitron/lang'); // always set langDir before lang.
|
||||
Validator::lang('en');
|
||||
|
||||
Validator::addRule('userAvailable', function($field, $value, array $params, array $fields) use ($user)
|
||||
{
|
||||
$userdata = $user->getUser($value);
|
||||
if($userdata){ return false; }
|
||||
return true;
|
||||
}, 'taken');
|
||||
|
||||
Validator::addRule('userExists', function($field, $value, array $params, array $fields) use ($user)
|
||||
{
|
||||
$userdata = $user->getUser($value);
|
||||
if($userdata){ return true; }
|
||||
return false;
|
||||
}, 'does not exist');
|
||||
|
||||
Validator::addRule('checkPassword', function($field, $value, array $params, array $fields) use ($user)
|
||||
{
|
||||
$userdata = $user->getUser($fields['username']);
|
||||
if($userdata && password_verify($value, $userdata['password'])){ return true; }
|
||||
return false;
|
||||
}, 'wrong password');
|
||||
|
||||
Validator::addRule('emailAvailable', function($field, $value, array $params, array $fields)
|
||||
{
|
||||
$email = 'testmail@gmail.com';
|
||||
if($email){ return false; }
|
||||
return true;
|
||||
}, 'taken');
|
||||
|
||||
Validator::addRule('emailKnown', function($field, $value, array $params, array $fields)
|
||||
{
|
||||
$email = 'testmail@gmail.com';
|
||||
if(!$email){ return false; }
|
||||
return true;
|
||||
}, 'unknown');
|
||||
|
||||
Validator::addRule('noSpecialChars', function($field, $value, array $params, array $fields)
|
||||
{
|
||||
$format = '/[!@#$%^&*()_+=\[\]{};\':"\\|,.<>\/?]/';
|
||||
if ( preg_match($format, $value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}, 'contains special characters');
|
||||
|
||||
Validator::addRule('noHTML', function($field, $value, array $params, array $fields)
|
||||
{
|
||||
if ( $value == strip_tags($value) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}, 'contains html');
|
||||
|
||||
Validator::addRule('markdownSecure', function($field, $value, array $params, array $fields)
|
||||
{
|
||||
/* strip out code blocks and blockquotes */
|
||||
$value = preg_replace('/`{4,}[\s\S]+?`{4,}/', '', $value);
|
||||
$value = preg_replace('/`{3,}[\s\S]+?`{3,}/', '', $value);
|
||||
$value = preg_replace('/`{2,}[\s\S]+?`{2,}/', '', $value);
|
||||
$value = preg_replace('/`{1,}[\s\S]+?`{1,}/', '', $value);
|
||||
$value = preg_replace('/>[\s\S]+?[\n\r]/', '', $value);
|
||||
|
||||
if ( $value == strip_tags($value) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}, 'not secure. For code please use markdown `inline-code` or ````fenced code blocks````.');
|
||||
}
|
||||
|
||||
/**
|
||||
* validation for signup form
|
||||
*
|
||||
* @param array $params with form data.
|
||||
* @return obj $v the validation object passed to a result method.
|
||||
*/
|
||||
|
||||
public function signin(array $params)
|
||||
{
|
||||
$v = new Validator($params);
|
||||
$v->rule('required', ['username', 'password'])->message("Required");
|
||||
$v->rule('alphaNum', 'username')->message("Invalid characters");
|
||||
$v->rule('lengthBetween', 'password', 5, 20)->message("Length between 5 - 20");
|
||||
$v->rule('lengthBetween', 'username', 3, 20)->message("Length between 3 - 20");
|
||||
|
||||
if($v->validate())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* validation for signup form
|
||||
*
|
||||
* @param array $params with form data.
|
||||
* @return obj $v the validation object passed to a result method.
|
||||
*/
|
||||
|
||||
public function newUser(array $params, $userroles)
|
||||
{
|
||||
$v = new Validator($params);
|
||||
$v->rule('required', ['username', 'email', 'password'])->message("required");
|
||||
$v->rule('alphaNum', 'username')->message("invalid characters");
|
||||
$v->rule('lengthBetween', 'password', 5, 20)->message("Length between 5 - 20");
|
||||
$v->rule('lengthBetween', 'username', 3, 20)->message("Length between 3 - 20");
|
||||
$v->rule('userAvailable', 'username')->message("User already exists");
|
||||
$v->rule('email', 'email')->message("e-mail is invalid");
|
||||
$v->rule('in', 'userrole', $userroles);
|
||||
|
||||
return $this->validationResult($v);
|
||||
}
|
||||
|
||||
public function existingUser(array $params, $userroles)
|
||||
{
|
||||
$v = new Validator($params);
|
||||
$v->rule('required', ['username', 'email', 'userrole'])->message("required");
|
||||
$v->rule('alphaNum', 'username')->message("invalid");
|
||||
$v->rule('lengthBetween', 'username', 3, 20)->message("Length between 3 - 20");
|
||||
$v->rule('userExists', 'username')->message("user does not exist");
|
||||
$v->rule('email', 'email')->message("e-mail is invalid");
|
||||
$v->rule('in', 'userrole', $userroles);
|
||||
|
||||
return $this->validationResult($v);
|
||||
}
|
||||
|
||||
public function username($username)
|
||||
{
|
||||
$v = new Validator($username);
|
||||
$v->rule('alphaNum', 'username')->message("Only alpha-numeric characters allowed");
|
||||
$v->rule('lengthBetween', 'username', 3, 20)->message("Length between 3 - 20");
|
||||
|
||||
return $this->validationResult($v);
|
||||
}
|
||||
|
||||
/**
|
||||
* validation for changing the password
|
||||
*
|
||||
* @param array $params with form data.
|
||||
* @return obj $v the validation object passed to a result method.
|
||||
*/
|
||||
|
||||
public function newPassword(array $params)
|
||||
{
|
||||
$v = new Validator($params);
|
||||
$v->rule('required', ['password', 'newpassword']);
|
||||
$v->rule('lengthBetween', 'newpassword', 5, 20);
|
||||
$v->rule('checkPassword', 'password')->message("Password is wrong");
|
||||
|
||||
return $this->validationResult($v);
|
||||
}
|
||||
|
||||
/**
|
||||
* validation for system settings
|
||||
*
|
||||
* @param array $params with form data.
|
||||
* @return obj $v the validation object passed to a result method.
|
||||
*/
|
||||
|
||||
public function settings(array $params, array $copyright, $name = false)
|
||||
{
|
||||
$v = new Validator($params);
|
||||
|
||||
$v->rule('required', ['title', 'author', 'copyright', 'year', 'editor']);
|
||||
$v->rule('lengthBetween', 'title', 2, 20);
|
||||
$v->rule('lengthBetween', 'author', 2, 40);
|
||||
$v->rule('regex', 'title', '/^[\pL0-9_ \-]*$/u');
|
||||
$v->rule('regex', 'author', '/^[\pL_ \-]*$/u');
|
||||
$v->rule('integer', 'year');
|
||||
$v->rule('length', 'year', 4);
|
||||
$v->rule('in', 'editor', ['raw', 'visual']);
|
||||
$v->rule('in', 'copyright', $copyright);
|
||||
|
||||
return $this->validationResult($v, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* validation for content editor
|
||||
*
|
||||
* @param array $params with form data.
|
||||
* @return true or $v->errors with array of errors to use in json-response
|
||||
*/
|
||||
|
||||
public function editorInput(array $params)
|
||||
{
|
||||
$v = new Validator($params);
|
||||
|
||||
$v->rule('required', ['title', 'content', 'url']);
|
||||
$v->rule('lengthBetween', 'title', 2, 100);
|
||||
$v->rule('noHTML', 'title');
|
||||
$v->rule('markdownSecure', 'content');
|
||||
|
||||
if($v->validate())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $v->errors();
|
||||
}
|
||||
}
|
||||
|
||||
public function blockInput(array $params)
|
||||
{
|
||||
$v = new Validator($params);
|
||||
|
||||
$v->rule('required', ['markdown', 'block_id', 'url']);
|
||||
$v->rule('markdownSecure', 'markdown');
|
||||
$v->rule('regex', 'block_id', '/^[0-9.]+$/i');
|
||||
|
||||
if($v->validate())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $v->errors();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* validation for resort navigation
|
||||
*
|
||||
* @param array $params with form data.
|
||||
* @return true or $v->errors with array of errors to use in json-response
|
||||
*/
|
||||
|
||||
public function navigationSort(array $params)
|
||||
{
|
||||
$v = new Validator($params);
|
||||
|
||||
$v->rule('required', ['item_id', 'parent_id_from', 'parent_id_to']);
|
||||
$v->rule('regex', 'item_id', '/^[0-9.]+$/i');
|
||||
$v->rule('regex', 'parent_id_from', '/^[a-zA-Z0-9.]+$/i');
|
||||
$v->rule('regex', 'parent_id_to', '/^[a-zA-Z0-9.]+$/i');
|
||||
$v->rule('integer', 'index_new');
|
||||
|
||||
if($v->validate())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $v->errors();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* validation for new navigation items
|
||||
*
|
||||
* @param array $params with form data.
|
||||
* @return true or $v->errors with array of errors to use in json-response
|
||||
*/
|
||||
|
||||
public function navigationItem(array $params)
|
||||
{
|
||||
$v = new Validator($params);
|
||||
|
||||
$v->rule('required', ['folder_id', 'item_name', 'type', 'url']);
|
||||
$v->rule('regex', 'folder_id', '/^[0-9.]+$/i');
|
||||
$v->rule('noSpecialChars', 'item_name');
|
||||
$v->rule('lengthBetween', 'item_name', 1, 40);
|
||||
$v->rule('in', 'type', ['file', 'folder']);
|
||||
|
||||
if($v->validate())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $v->errors();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* validation for dynamic fields ( settings for themes and plugins)
|
||||
*
|
||||
* @param string $fieldName with the name of the field.
|
||||
* @param array or string $fieldValue with the values of the field.
|
||||
* @param string $objectName with the name of the plugin or theme.
|
||||
* @param array $fieldDefinitions with the field definitions as multi-dimensional array.
|
||||
* @return obj $v the validation object passed to a result method.
|
||||
*/
|
||||
|
||||
public function objectField($fieldName, $fieldValue, $objectName, $fieldDefinitions)
|
||||
{
|
||||
$v = new Validator(array($fieldName => $fieldValue));
|
||||
|
||||
if(isset($fieldDefinitions['required']))
|
||||
{
|
||||
$v->rule('required', $fieldName);
|
||||
}
|
||||
|
||||
switch($fieldDefinitions['type'])
|
||||
{
|
||||
case "select":
|
||||
/* create array with option keys as value */
|
||||
$options = array();
|
||||
foreach($fieldDefinitions['options'] as $key => $value){ $options[] = $key; }
|
||||
$v->rule('in', $fieldName, $options);
|
||||
break;
|
||||
case "radio":
|
||||
$v->rule('in', $fieldName, $fieldDefinitions['options']);
|
||||
break;
|
||||
case "checkboxlist":
|
||||
/* create array with option keys as value */
|
||||
$options = array();
|
||||
foreach($fieldDefinitions['options'] as $key => $value){ $options[] = $key; }
|
||||
/* loop over input values and check, if the options of the field definitions (options for checkboxlist) contains the key (input from user, key is used as value, value is used as label) */
|
||||
foreach($fieldValue as $key => $value)
|
||||
{
|
||||
$v->rule('in', $key, $options);
|
||||
}
|
||||
break;
|
||||
case "color":
|
||||
$v->rule('regex', $fieldName, '/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/');
|
||||
break;
|
||||
case "email":
|
||||
$v->rule('email', $fieldName);
|
||||
break;
|
||||
case "date":
|
||||
$v->rule('date', $fieldName);
|
||||
break;
|
||||
case "checkbox":
|
||||
$v->rule('accepted', $fieldName);
|
||||
break;
|
||||
case "url":
|
||||
$v->rule('lengthMax', $fieldName, 200);
|
||||
$v->rule('url', $fieldName);
|
||||
break;
|
||||
case "text":
|
||||
$v->rule('lengthMax', $fieldName, 200);
|
||||
$v->rule('regex', $fieldName, '/^[\pL0-9_ \-\.\?\!\/\:]*$/u');
|
||||
break;
|
||||
case "textarea":
|
||||
$v->rule('lengthMax', $fieldName, 1000);
|
||||
$v->rule('noHTML', $fieldName);
|
||||
// $v->rule('regex', $fieldName, '/<[^<]+>/');
|
||||
break;
|
||||
case "paragraph":
|
||||
$v->rule('lengthMax', $fieldName, 1000);
|
||||
$v->rule('noHTML', $fieldName);
|
||||
break;
|
||||
case "password":
|
||||
$v->rule('lengthMax', $fieldName, 100);
|
||||
break;
|
||||
default:
|
||||
$v->rule('lengthMax', $fieldName, 1000);
|
||||
$v->rule('regex', $fieldName, '/^[\pL0-9_ \-]*$/u');
|
||||
}
|
||||
|
||||
return $this->validationResult($v, $objectName);
|
||||
}
|
||||
|
||||
/**
|
||||
* result for validation
|
||||
*
|
||||
* @param obj $v the validation object.
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
public function validationResult($v, $name = false)
|
||||
{
|
||||
if($v->validate())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if($name)
|
||||
{
|
||||
if(isset($_SESSION['errors'][$name]))
|
||||
{
|
||||
foreach ($v->errors() as $key => $val)
|
||||
{
|
||||
$_SESSION['errors'][$name][$key] = $val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$_SESSION['errors'][$name] = $v->errors();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$_SESSION['errors'] = $v->errors();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,25 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
class VersionCheck
|
||||
{
|
||||
function checkVersion($url)
|
||||
{
|
||||
$opts = array(
|
||||
'http'=>array(
|
||||
'method' => "GET",
|
||||
'header' => "Referer: $url\r\n"
|
||||
)
|
||||
);
|
||||
|
||||
$context = stream_context_create($opts);
|
||||
|
||||
if(false === ($version = @file_get_contents('http://typemill.net/api/v1/checkversion', false, $context)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$version = json_decode($version);
|
||||
return $version->system->typemill;
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
class VersionCheck
|
||||
{
|
||||
function checkVersion($url)
|
||||
{
|
||||
$opts = array(
|
||||
'http'=>array(
|
||||
'method' => "GET",
|
||||
'header' => "Referer: $url\r\n"
|
||||
)
|
||||
);
|
||||
|
||||
$context = stream_context_create($opts);
|
||||
|
||||
if(false === ($version = @file_get_contents('http://typemill.net/api/v1/checkversion', false, $context)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$version = json_decode($version);
|
||||
return $version->system->typemill;
|
||||
}
|
||||
}
|
@@ -1,131 +1,160 @@
|
||||
<?php
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
class Write
|
||||
{
|
||||
protected $basePath;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$basePath = getcwd() . DIRECTORY_SEPARATOR;
|
||||
$this->basePath = $basePath;
|
||||
}
|
||||
|
||||
public function checkPath($folder)
|
||||
{
|
||||
$folderPath = $this->basePath . $folder;
|
||||
|
||||
if(!is_dir($folderPath))
|
||||
{
|
||||
if(@mkdir($folderPath, 0774, true))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
# throw new \Exception("The folder '{$folder}' is missing and we could not create it. Please create the folder manually on your server.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(@is_writable($folderPath))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
# throw new \Exception("Please make the folder '{$folder}' writable.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function checkFile($folder, $file)
|
||||
{
|
||||
if(!file_exists($this->basePath . $folder . DIRECTORY_SEPARATOR . $file))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function writeFile($folder, $file, $data)
|
||||
{
|
||||
if($this->checkPath($folder))
|
||||
{
|
||||
$filePath = $this->basePath . $folder . DIRECTORY_SEPARATOR . $file;
|
||||
|
||||
$openFile = @fopen($filePath, "w");
|
||||
|
||||
if(!$openFile)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
fwrite($openFile, $data);
|
||||
fclose($openFile);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getFile($folderName, $fileName)
|
||||
{
|
||||
if($this->checkFile($folderName, $fileName))
|
||||
{
|
||||
$fileContent = file_get_contents($folderName . DIRECTORY_SEPARATOR . $fileName);
|
||||
return $fileContent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function moveElement($item, $folderPath, $index)
|
||||
{
|
||||
$filetypes = array('md', 'txt');
|
||||
|
||||
# set new order as string
|
||||
$newOrder = ($index < 10) ? '0' . $index : $index;
|
||||
|
||||
# create new path with foldername or filename but without file-type
|
||||
$newPath = $this->basePath . 'content' . $folderPath . DIRECTORY_SEPARATOR . $newOrder . '-' . str_replace(" ", "-", $item->name);
|
||||
|
||||
if($item->elementType == 'folder')
|
||||
{
|
||||
$oldPath = $this->basePath . 'content' . $item->path;
|
||||
if(@rename($oldPath, $newPath))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
# create old path but without filetype
|
||||
$oldPath = substr($item->path, 0, strpos($item->path, "."));
|
||||
$oldPath = $this->basePath . 'content' . $oldPath;
|
||||
|
||||
$result = true;
|
||||
|
||||
foreach($filetypes as $filetype)
|
||||
{
|
||||
$oldFilePath = $oldPath . '.' . $filetype;
|
||||
$newFilePath = $newPath . '.' . $filetype;
|
||||
|
||||
#check if file with filetype exists and rename
|
||||
if($oldFilePath != $newFilePath && file_exists($oldFilePath))
|
||||
{
|
||||
if(@rename($oldFilePath, $newFilePath))
|
||||
{
|
||||
$result = $result;
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
class Write
|
||||
{
|
||||
protected $basePath;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$basePath = getcwd() . DIRECTORY_SEPARATOR;
|
||||
$this->basePath = $basePath;
|
||||
}
|
||||
|
||||
public function checkPath($folder)
|
||||
{
|
||||
$folderPath = $this->basePath . $folder;
|
||||
|
||||
if(!is_dir($folderPath))
|
||||
{
|
||||
if(@mkdir($folderPath, 0774, true))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
# throw new \Exception("The folder '{$folder}' is missing and we could not create it. Please create the folder manually on your server.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(@is_writable($folderPath))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
# throw new \Exception("Please make the folder '{$folder}' writable.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function checkFile($folder, $file)
|
||||
{
|
||||
if(!file_exists($this->basePath . $folder . DIRECTORY_SEPARATOR . $file))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function checkFileWithPath($filepath)
|
||||
{
|
||||
if(!file_exists($this->basePath . $filepath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function writeFile($folder, $file, $data)
|
||||
{
|
||||
if($this->checkPath($folder))
|
||||
{
|
||||
$filePath = $this->basePath . $folder . DIRECTORY_SEPARATOR . $file;
|
||||
|
||||
$openFile = @fopen($filePath, "w");
|
||||
|
||||
if(!$openFile)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
fwrite($openFile, $data);
|
||||
fclose($openFile);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getFile($folderName, $fileName)
|
||||
{
|
||||
if($this->checkFile($folderName, $fileName))
|
||||
{
|
||||
$fileContent = file_get_contents($folderName . DIRECTORY_SEPARATOR . $fileName);
|
||||
return $fileContent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getFileWithPath($filepath)
|
||||
{
|
||||
if($this->checkFileWithPath($filepath))
|
||||
{
|
||||
$fileContent = file_get_contents($filepath);
|
||||
return $fileContent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function deleteFileWithPath($filepath)
|
||||
{
|
||||
if($this->checkFileWithPath($filepath))
|
||||
{
|
||||
unlink($this->basePath . $filepath);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function moveElement($item, $folderPath, $index)
|
||||
{
|
||||
$filetypes = array('md', 'txt');
|
||||
|
||||
# set new order as string
|
||||
$newOrder = ($index < 10) ? '0' . $index : $index;
|
||||
|
||||
# create new path with foldername or filename but without file-type
|
||||
$newPath = $this->basePath . 'content' . $folderPath . DIRECTORY_SEPARATOR . $newOrder . '-' . str_replace(" ", "-", $item->name);
|
||||
|
||||
if($item->elementType == 'folder')
|
||||
{
|
||||
$oldPath = $this->basePath . 'content' . $item->path;
|
||||
if(@rename($oldPath, $newPath))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
# create old path but without filetype
|
||||
$oldPath = substr($item->path, 0, strpos($item->path, "."));
|
||||
$oldPath = $this->basePath . 'content' . $oldPath;
|
||||
|
||||
$result = true;
|
||||
|
||||
foreach($filetypes as $filetype)
|
||||
{
|
||||
$oldFilePath = $oldPath . '.' . $filetype;
|
||||
$newFilePath = $newPath . '.' . $filetype;
|
||||
|
||||
#check if file with filetype exists and rename
|
||||
if($oldFilePath != $newFilePath && file_exists($oldFilePath))
|
||||
{
|
||||
if(@rename($oldFilePath, $newFilePath))
|
||||
{
|
||||
$result = $result;
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
@@ -1,84 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
class WriteCache extends Write
|
||||
{
|
||||
/**
|
||||
* Validates, if the cache is valid or invalid and has to be refreshed
|
||||
* @param int $duration how many seconds the cache is valid.
|
||||
* @return boolean for an invalid cache (false) and for a valid cache (true).
|
||||
*/
|
||||
public function validate($folderName, $fileName, $duration)
|
||||
{
|
||||
if(isset($_SERVER['HTTP_CACHE_CONTROL']) && $_SERVER['HTTP_CACHE_CONTROL'] == 'max-age=0')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!$this->checkPath($folderName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!$this->checkFile($folderName, $fileName))
|
||||
{
|
||||
$this->writeFile($folderName, $fileName, time());
|
||||
return false;
|
||||
}
|
||||
|
||||
$lastRefresh = file_get_contents($folderName . DIRECTORY_SEPARATOR . $fileName);
|
||||
|
||||
if(time() - $lastRefresh > $duration)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a cache file.
|
||||
* Serializes an object and writes it to the cache file together with a file that holds the last refresh time.
|
||||
* @param object $cacheData has to be an object (e.g. navigation object).
|
||||
* @param string $cacheFile has to be the name of the file you want to update (in case there are more than one cache files.
|
||||
*/
|
||||
public function updateCache($folderName, $cacheFileName, $requestFileName, $cacheData)
|
||||
{
|
||||
$sCacheData = serialize($cacheData);
|
||||
$this->writeFile($folderName, $cacheFileName, $sCacheData);
|
||||
if($requestFileName)
|
||||
{
|
||||
$this->writeFile($folderName, $requestFileName, time());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the recent cache.
|
||||
* Takes a filename, gets the file and unserializes the cache into an object.
|
||||
* @param string $fileName is the name of the cache file.
|
||||
*/
|
||||
public function getCache($folderName, $cacheFileName)
|
||||
{
|
||||
$sCacheData = $this->getFile($folderName, $cacheFileName);
|
||||
if($sCacheData)
|
||||
{
|
||||
return unserialize($sCacheData);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Create a function to clear a specific cache file
|
||||
*/
|
||||
public function clearCache($name)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Create a function to clear all cache files
|
||||
*/
|
||||
public function clearAllCacheFiles()
|
||||
{
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
class WriteCache extends Write
|
||||
{
|
||||
/**
|
||||
* Validates, if the cache is valid or invalid and has to be refreshed
|
||||
* @param int $duration how many seconds the cache is valid.
|
||||
* @return boolean for an invalid cache (false) and for a valid cache (true).
|
||||
*/
|
||||
public function validate($folderName, $fileName, $duration)
|
||||
{
|
||||
if(isset($_SERVER['HTTP_CACHE_CONTROL']) && $_SERVER['HTTP_CACHE_CONTROL'] == 'max-age=0')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!$this->checkPath($folderName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!$this->checkFile($folderName, $fileName))
|
||||
{
|
||||
$this->writeFile($folderName, $fileName, time());
|
||||
return false;
|
||||
}
|
||||
|
||||
$lastRefresh = file_get_contents($folderName . DIRECTORY_SEPARATOR . $fileName);
|
||||
|
||||
if(time() - $lastRefresh > $duration)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a cache file.
|
||||
* Serializes an object and writes it to the cache file together with a file that holds the last refresh time.
|
||||
* @param object $cacheData has to be an object (e.g. navigation object).
|
||||
* @param string $cacheFile has to be the name of the file you want to update (in case there are more than one cache files.
|
||||
*/
|
||||
public function updateCache($folderName, $cacheFileName, $requestFileName, $cacheData)
|
||||
{
|
||||
$sCacheData = serialize($cacheData);
|
||||
$this->writeFile($folderName, $cacheFileName, $sCacheData);
|
||||
if($requestFileName)
|
||||
{
|
||||
$this->writeFile($folderName, $requestFileName, time());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the recent cache.
|
||||
* Takes a filename, gets the file and unserializes the cache into an object.
|
||||
* @param string $fileName is the name of the cache file.
|
||||
*/
|
||||
public function getCache($folderName, $cacheFileName)
|
||||
{
|
||||
$sCacheData = $this->getFile($folderName, $cacheFileName);
|
||||
if($sCacheData)
|
||||
{
|
||||
return unserialize($sCacheData);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Create a function to clear a specific cache file
|
||||
*/
|
||||
public function clearCache($name)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Create a function to clear all cache files
|
||||
*/
|
||||
public function clearAllCacheFiles()
|
||||
{
|
||||
}
|
||||
}
|
@@ -1,45 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
class WriteSitemap extends Write
|
||||
{
|
||||
public function updateSitemap($folderName, $sitemapFileName, $requestFileName, $data, $baseUrl)
|
||||
{
|
||||
$sitemap = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
|
||||
$sitemap .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
|
||||
$sitemap = $this->addUrlSet($sitemap, $baseUrl);
|
||||
$sitemap .= $this->generateUrlSets($data);
|
||||
$sitemap .= '</urlset>';
|
||||
|
||||
$this->writeFile($folderName, $sitemapFileName, $sitemap);
|
||||
$this->writeFile($folderName, $requestFileName, time());
|
||||
}
|
||||
|
||||
public function generateUrlSets($data)
|
||||
{
|
||||
$urlset = '';
|
||||
|
||||
foreach($data as $item)
|
||||
{
|
||||
if($item->elementType == 'folder')
|
||||
{
|
||||
$urlset = $this->addUrlSet($urlset, $item->urlAbs);
|
||||
$urlset .= $this->generateUrlSets($item->folderContent, $urlset);
|
||||
}
|
||||
else
|
||||
{
|
||||
$urlset = $this->addUrlSet($urlset, $item->urlAbs);
|
||||
}
|
||||
}
|
||||
return $urlset;
|
||||
}
|
||||
|
||||
public function addUrlSet($urlset, $url)
|
||||
{
|
||||
$urlset .= ' <url>' . "\n";
|
||||
$urlset .= ' <loc>' . $url . '</loc>' . "\n";
|
||||
$urlset .= ' </url>' . "\n";
|
||||
return $urlset;
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
class WriteSitemap extends Write
|
||||
{
|
||||
public function updateSitemap($folderName, $sitemapFileName, $requestFileName, $data, $baseUrl)
|
||||
{
|
||||
$sitemap = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
|
||||
$sitemap .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
|
||||
$sitemap = $this->addUrlSet($sitemap, $baseUrl);
|
||||
$sitemap .= $this->generateUrlSets($data);
|
||||
$sitemap .= '</urlset>';
|
||||
|
||||
$this->writeFile($folderName, $sitemapFileName, $sitemap);
|
||||
$this->writeFile($folderName, $requestFileName, time());
|
||||
}
|
||||
|
||||
public function generateUrlSets($data)
|
||||
{
|
||||
$urlset = '';
|
||||
|
||||
foreach($data as $item)
|
||||
{
|
||||
if($item->elementType == 'folder')
|
||||
{
|
||||
$urlset = $this->addUrlSet($urlset, $item->urlAbs);
|
||||
$urlset .= $this->generateUrlSets($item->folderContent, $urlset);
|
||||
}
|
||||
else
|
||||
{
|
||||
$urlset = $this->addUrlSet($urlset, $item->urlAbs);
|
||||
}
|
||||
}
|
||||
return $urlset;
|
||||
}
|
||||
|
||||
public function addUrlSet($urlset, $url)
|
||||
{
|
||||
$urlset .= ' <url>' . "\n";
|
||||
$urlset .= ' <loc>' . $url . '</loc>' . "\n";
|
||||
$urlset .= ' </url>' . "\n";
|
||||
return $urlset;
|
||||
}
|
||||
}
|
@@ -1,38 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
class WriteYaml extends Write
|
||||
{
|
||||
/**
|
||||
* Get the a yaml file.
|
||||
* @param string $fileName is the name of the Yaml Folder.
|
||||
* @param string $yamlFileName is the name of the Yaml File.
|
||||
*/
|
||||
public function getYaml($folderName, $yamlFileName)
|
||||
{
|
||||
$yaml = $this->getFile($folderName, $yamlFileName);
|
||||
|
||||
if($yaml)
|
||||
{
|
||||
return \Symfony\Component\Yaml\Yaml::parse($yaml);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a yaml file.
|
||||
* @param string $fileName is the name of the Yaml Folder.
|
||||
* @param string $yamlFileName is the name of the Yaml File.
|
||||
* @param array $contentArray is the content as an array.
|
||||
*/
|
||||
public function updateYaml($folderName, $yamlFileName, $contentArray)
|
||||
{
|
||||
$yaml = \Symfony\Component\Yaml\Yaml::dump($contentArray,6);
|
||||
if($this->writeFile($folderName, $yamlFileName, $yaml))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
class WriteYaml extends Write
|
||||
{
|
||||
/**
|
||||
* Get the a yaml file.
|
||||
* @param string $fileName is the name of the Yaml Folder.
|
||||
* @param string $yamlFileName is the name of the Yaml File.
|
||||
*/
|
||||
public function getYaml($folderName, $yamlFileName)
|
||||
{
|
||||
$yaml = $this->getFile($folderName, $yamlFileName);
|
||||
|
||||
if($yaml)
|
||||
{
|
||||
return \Symfony\Component\Yaml\Yaml::parse($yaml);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a yaml file.
|
||||
* @param string $fileName is the name of the Yaml Folder.
|
||||
* @param string $yamlFileName is the name of the Yaml File.
|
||||
* @param array $contentArray is the content as an array.
|
||||
*/
|
||||
public function updateYaml($folderName, $yamlFileName, $contentArray)
|
||||
{
|
||||
$yaml = \Symfony\Component\Yaml\Yaml::dump($contentArray,6);
|
||||
if($this->writeFile($folderName, $yamlFileName, $yaml))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user