import from la bonne adresse and first refactoring for ouidade.com
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\ArrayTraits;
|
||||
|
||||
/**
|
||||
* Implements ArrayAccess interface.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\ArrayTraits
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*
|
||||
* @property array $items
|
||||
*/
|
||||
trait ArrayAccess
|
||||
{
|
||||
/**
|
||||
* Whether or not an offset exists.
|
||||
*
|
||||
* @param mixed $offset An offset to check for.
|
||||
* @return bool Returns TRUE on success or FALSE on failure.
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->items[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value at specified offset.
|
||||
*
|
||||
* @param mixed $offset The offset to retrieve.
|
||||
* @return mixed Can return all value types.
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return isset($this->items[$offset]) ? $this->items[$offset] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a value to the specified offset.
|
||||
*
|
||||
* @param mixed $offset The offset to assign the value to.
|
||||
* @param mixed $value The value to set.
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
if (is_null($offset)) {
|
||||
$this->items[] = $value;
|
||||
} else {
|
||||
$this->items[$offset] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsets an offset.
|
||||
*
|
||||
* @param mixed $offset The offset to unset.
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
// Hack to make Iterator trait work together with unset.
|
||||
if (isset($this->iteratorUnset) && $offset == key($this->items)) {
|
||||
$this->iteratorUnset = true;
|
||||
}
|
||||
|
||||
unset($this->items[$offset]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\ArrayTraits;
|
||||
|
||||
/**
|
||||
* Implements getters and setters.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\ArrayTraits
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
trait ArrayAccessWithGetters
|
||||
{
|
||||
use ArrayAccess;
|
||||
|
||||
/**
|
||||
* Magic setter method
|
||||
*
|
||||
* @param mixed $offset Asset name value
|
||||
* @param mixed $value Asset value
|
||||
*/
|
||||
public function __set($offset, $value)
|
||||
{
|
||||
$this->offsetSet($offset, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic getter method
|
||||
*
|
||||
* @param mixed $offset Asset name value
|
||||
* @return mixed Asset value
|
||||
*/
|
||||
public function __get($offset)
|
||||
{
|
||||
return $this->offsetGet($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method to determine if the attribute is set
|
||||
*
|
||||
* @param mixed $offset Asset name value
|
||||
* @return boolean True if the value is set
|
||||
*/
|
||||
public function __isset($offset)
|
||||
{
|
||||
return $this->offsetExists($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method to unset the attribute
|
||||
*
|
||||
* @param mixed $offset The name value to unset
|
||||
*/
|
||||
public function __unset($offset)
|
||||
{
|
||||
$this->offsetUnset($offset);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\ArrayTraits;
|
||||
|
||||
/**
|
||||
* Implements Constructor for setting items.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\ArrayTraits
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*
|
||||
* @property array $items
|
||||
*/
|
||||
trait Constructor
|
||||
{
|
||||
/**
|
||||
* Constructor to initialize array.
|
||||
*
|
||||
* @param array $items Initial items inside the iterator.
|
||||
*/
|
||||
public function __construct(array $items = array())
|
||||
{
|
||||
$this->items = $items;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\ArrayTraits;
|
||||
|
||||
/**
|
||||
* Implements \Countable interface.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\ArrayTraits
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*
|
||||
* @property array $items
|
||||
*/
|
||||
trait Countable
|
||||
{
|
||||
/**
|
||||
* Implements Countable interface.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->items);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\ArrayTraits;
|
||||
|
||||
use Symfony\Component\Yaml\Exception\DumpException;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
/**
|
||||
* Implements ExportInterface.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\ArrayTraits
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*
|
||||
* @property array $items
|
||||
*/
|
||||
trait Export
|
||||
{
|
||||
/**
|
||||
* Convert object into an array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert object into YAML string.
|
||||
*
|
||||
* @param int $inline The level where you switch to inline YAML.
|
||||
* @param int $indent The amount of spaces to use for indentation of nested nodes.
|
||||
*
|
||||
* @return string A YAML string representing the object.
|
||||
* @throws DumpException
|
||||
*/
|
||||
public function toYaml($inline = 3, $indent = 2)
|
||||
{
|
||||
return Yaml::dump($this->toArray(), $inline, $indent, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert object into JSON string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toJson()
|
||||
{
|
||||
return json_encode($this->toArray());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\ArrayTraits;
|
||||
|
||||
/**
|
||||
* Defines Export interface.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\ArrayTraits
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
interface ExportInterface
|
||||
{
|
||||
/**
|
||||
* Convert object into an array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray();
|
||||
|
||||
/**
|
||||
* Convert object into YAML string.
|
||||
*
|
||||
* @param int $inline
|
||||
* @param int $indent
|
||||
* @return string
|
||||
*/
|
||||
public function toYaml($inline = 3, $indent = 2);
|
||||
|
||||
/**
|
||||
* Convert object into JSON string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toJson();
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\ArrayTraits;
|
||||
|
||||
/**
|
||||
* Implements \Iterator interface.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\ArrayTraits
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*
|
||||
* @property array $items
|
||||
*/
|
||||
trait Iterator
|
||||
{
|
||||
/**
|
||||
* Hack to make Iterator work together with unset().
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $iteratorUnset = false;
|
||||
|
||||
/**
|
||||
* Returns the current element.
|
||||
*
|
||||
* @return mixed Can return any type.
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return current($this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key of the current element.
|
||||
*
|
||||
* @return mixed Returns scalar on success, or NULL on failure.
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return key($this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the current position to the next element.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
if ($this->iteratorUnset) {
|
||||
// If current item was unset, position is already in the next element (do nothing).
|
||||
$this->iteratorUnset = false;
|
||||
} else {
|
||||
next($this->items);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewinds back to the first element of the Iterator.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->iteratorUnset = false;
|
||||
reset($this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called after Iterator::rewind() and Iterator::next() to check if the current position is valid.
|
||||
*
|
||||
* @return bool Returns TRUE on success or FALSE on failure.
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return key($this->items) !== null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\ArrayTraits;
|
||||
|
||||
/**
|
||||
* Implements nested ArrayAccess interface with dot notation.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\ArrayTraits
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*
|
||||
* @property array $items
|
||||
*/
|
||||
trait NestedArrayAccess
|
||||
{
|
||||
/**
|
||||
* Get value by using dot notation for nested arrays/objects.
|
||||
*
|
||||
* @example $value = $this->get('this.is.my.nested.variable');
|
||||
*
|
||||
* @param string $name Dot separated path to the requested value.
|
||||
* @param mixed $default Default value (or null).
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return mixed Value.
|
||||
*/
|
||||
public function get($name, $default = null, $separator = '.')
|
||||
{
|
||||
$path = explode($separator, $name);
|
||||
$current = $this->items;
|
||||
foreach ($path as $field) {
|
||||
if (is_object($current) && isset($current->{$field})) {
|
||||
$current = $current->{$field};
|
||||
} elseif (is_array($current) && isset($current[$field])) {
|
||||
$current = $current[$field];
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
return $current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set value by using dot notation for nested arrays/objects.
|
||||
*
|
||||
* @example $data->set('this.is.my.nested.variable', $value);
|
||||
*
|
||||
* @param string $name Dot separated path to the requested value.
|
||||
* @param mixed $value New value.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return $this
|
||||
*/
|
||||
public function set($name, $value, $separator = '.')
|
||||
{
|
||||
$path = explode($separator, $name);
|
||||
$current = &$this->items;
|
||||
foreach ($path as $field) {
|
||||
if (is_object($current)) {
|
||||
// Handle objects.
|
||||
if (!isset($current->{$field})) {
|
||||
$current->{$field} = array();
|
||||
}
|
||||
$current = &$current->{$field};
|
||||
} else {
|
||||
// Handle arrays and scalars.
|
||||
if (!is_array($current)) {
|
||||
$current = array($field => array());
|
||||
} elseif (!isset($current[$field])) {
|
||||
$current[$field] = array();
|
||||
}
|
||||
$current = &$current[$field];
|
||||
}
|
||||
}
|
||||
|
||||
$current = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset value by using dot notation for nested arrays/objects.
|
||||
*
|
||||
* @example $data->remove('this.is.my.nested.variable');
|
||||
*
|
||||
* @param string $name Dot separated path to the requested value.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return $this
|
||||
*/
|
||||
public function remove($name, $separator = '.')
|
||||
{
|
||||
if ($name === '') {
|
||||
$this->items = [];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
$path = explode($separator, $name);
|
||||
$var = array_pop($path);
|
||||
$current = &$this->items;
|
||||
|
||||
foreach ($path as $field) {
|
||||
if (is_object($current)) {
|
||||
// Handle objects.
|
||||
if (!isset($current->{$field})) {
|
||||
return $this;
|
||||
}
|
||||
$current = &$current->{$field};
|
||||
} else {
|
||||
// Handle arrays and scalars.
|
||||
if (!is_array($current) || !isset($current[$field])) {
|
||||
return $this;
|
||||
}
|
||||
$current = &$current[$field];
|
||||
}
|
||||
}
|
||||
|
||||
unset($current[$var]);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default value by using dot notation for nested arrays/objects.
|
||||
*
|
||||
* @example $data->def('this.is.my.nested.variable', 'default');
|
||||
*
|
||||
* @param string $name Dot separated path to the requested value.
|
||||
* @param mixed $default Default value (or null).
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return $this
|
||||
*/
|
||||
public function def($name, $default = null, $separator = '.')
|
||||
{
|
||||
$this->set($name, $this->get($name, $default, $separator), $separator);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not an offset exists.
|
||||
*
|
||||
* @param mixed $offset An offset to check for.
|
||||
* @return bool Returns TRUE on success or FALSE on failure.
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return $this->get($offset) !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value at specified offset.
|
||||
*
|
||||
* @param mixed $offset The offset to retrieve.
|
||||
* @return mixed Can return all value types.
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->get($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a value to the specified offset.
|
||||
*
|
||||
* @param mixed $offset The offset to assign the value to.
|
||||
* @param mixed $value The value to set.
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
if (is_null($offset)) {
|
||||
$this->items[] = $value;
|
||||
} else {
|
||||
$this->set($offset, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsets variable at specified offset.
|
||||
*
|
||||
* @param $offset
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
if (is_null($offset)) {
|
||||
$this->items[] = [];
|
||||
} else {
|
||||
$this->remove($offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\ArrayTraits;
|
||||
|
||||
/**
|
||||
* Implements getters and setters.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\ArrayTraits
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
trait NestedArrayAccessWithGetters
|
||||
{
|
||||
use NestedArrayAccess;
|
||||
|
||||
/**
|
||||
* Magic setter method
|
||||
*
|
||||
* @param mixed $offset Asset name value
|
||||
* @param mixed $value Asset value
|
||||
*/
|
||||
public function __set($offset, $value)
|
||||
{
|
||||
$this->offsetSet($offset, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic getter method
|
||||
*
|
||||
* @param mixed $offset Asset name value
|
||||
* @return mixed Asset value
|
||||
*/
|
||||
public function __get($offset)
|
||||
{
|
||||
return $this->offsetGet($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method to determine if the attribute is set
|
||||
*
|
||||
* @param mixed $offset Asset name value
|
||||
* @return boolean True if the value is set
|
||||
*/
|
||||
public function __isset($offset)
|
||||
{
|
||||
return $this->offsetExists($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method to unset the attribute
|
||||
*
|
||||
* @param mixed $offset The name value to unset
|
||||
*/
|
||||
public function __unset($offset)
|
||||
{
|
||||
$this->offsetUnset($offset);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\ArrayTraits;
|
||||
|
||||
/**
|
||||
* Implements \Serializable interface.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\ArrayTraits
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*
|
||||
* @property array $items
|
||||
*/
|
||||
trait Serializable
|
||||
{
|
||||
/**
|
||||
* Returns string representation of the object.
|
||||
*
|
||||
* @return string Returns the string representation of the object.
|
||||
*/
|
||||
public function serialize()
|
||||
{
|
||||
return serialize($this->items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called during unserialization of the object.
|
||||
*
|
||||
* @param string $serialized The string representation of the object.
|
||||
*/
|
||||
public function unserialize($serialized)
|
||||
{
|
||||
$this->items = unserialize($serialized);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,369 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\Blueprints;
|
||||
|
||||
/**
|
||||
* Blueprints can be used to define a data structure.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\Blueprints
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Blueprints
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $items = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $rules = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $nested = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $filter = ['validation' => true];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $serialized Serialized content if available.
|
||||
*/
|
||||
public function __construct(array $serialized = null)
|
||||
{
|
||||
if ($serialized) {
|
||||
$this->items = (array) $serialized['items'];
|
||||
$this->rules = (array) $serialized['rules'];
|
||||
$this->nested = (array) $serialized['nested'];
|
||||
$this->filter = (array) $serialized['filter'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set filter for inherited properties.
|
||||
*
|
||||
* @param array $filter List of field names to be inherited.
|
||||
*/
|
||||
public function setFilter(array $filter)
|
||||
{
|
||||
$this->filter = array_flip($filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value by using dot notation for nested arrays/objects.
|
||||
*
|
||||
* @example $value = $data->get('this.is.my.nested.variable');
|
||||
*
|
||||
* @param string $name Dot separated path to the requested value.
|
||||
* @param mixed $default Default value (or null).
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
*
|
||||
* @return mixed Value.
|
||||
*/
|
||||
public function get($name, $default = null, $separator = '.')
|
||||
{
|
||||
$name = $separator != '.' ? strtr($name, $separator, '.') : $name;
|
||||
|
||||
return isset($this->items[$name]) ? $this->items[$name] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set value by using dot notation for nested arrays/objects.
|
||||
*
|
||||
* @example $value = $data->set('this.is.my.nested.variable', $newField);
|
||||
*
|
||||
* @param string $name Dot separated path to the requested value.
|
||||
* @param mixed $value New value.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
*/
|
||||
public function set($name, $value, $separator = '.')
|
||||
{
|
||||
$name = $separator != '.' ? strtr($name, $separator, '.') : $name;
|
||||
|
||||
$this->items[$name] = $value;
|
||||
$this->addProperty($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define value by using dot notation for nested arrays/objects.
|
||||
*
|
||||
* @example $value = $data->set('this.is.my.nested.variable', true);
|
||||
*
|
||||
* @param string $name Dot separated path to the requested value.
|
||||
* @param mixed $value New value.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
*/
|
||||
public function def($name, $value, $separator = '.')
|
||||
{
|
||||
$this->set($name, $this->get($name, $value, $separator), $separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert object into an array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return ['items' => $this->items, 'rules' => $this->rules, 'nested' => $this->nested, 'filter' => $this->filter];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get nested structure containing default values defined in the blueprints.
|
||||
*
|
||||
* Fields without default value are ignored in the list.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDefaults()
|
||||
{
|
||||
return $this->buildDefaults($this->nested);
|
||||
}
|
||||
|
||||
/**
|
||||
* Embed an array to the blueprint.
|
||||
*
|
||||
* @param $name
|
||||
* @param array $value
|
||||
* @param string $separator
|
||||
* @return $this
|
||||
*/
|
||||
public function embed($name, array $value, $separator = '.')
|
||||
{
|
||||
if (isset($value['rules'])) {
|
||||
$this->rules = array_merge($this->rules, $value['rules']);
|
||||
}
|
||||
if (!isset($value['form']['fields']) || !is_array($value['form']['fields'])) {
|
||||
return $this;
|
||||
}
|
||||
$prefix = $name ? ($separator != '.' ? strtr($name, $separator, '.') : $name) . '.' : '';
|
||||
$params = array_intersect_key($this->filter, $value);
|
||||
$this->parseFormFields($value['form']['fields'], $params, $prefix);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge two arrays by using blueprints.
|
||||
*
|
||||
* @param array $data1
|
||||
* @param array $data2
|
||||
* @param string $name Optional
|
||||
* @param string $separator Optional
|
||||
* @return array
|
||||
*/
|
||||
public function mergeData(array $data1, array $data2, $name = null, $separator = '.')
|
||||
{
|
||||
$nested = $this->getProperty($name, $separator);
|
||||
return $this->mergeArrays($data1, $data2, $nested);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $nested
|
||||
* @return array
|
||||
*/
|
||||
protected function buildDefaults(array &$nested)
|
||||
{
|
||||
$defaults = [];
|
||||
|
||||
foreach ($nested as $key => $value) {
|
||||
if ($key === '*') {
|
||||
// TODO: Add support for adding defaults to collections.
|
||||
continue;
|
||||
}
|
||||
if (is_array($value)) {
|
||||
// Recursively fetch the items.
|
||||
$list = $this->buildDefaults($value);
|
||||
|
||||
// Only return defaults if there are any.
|
||||
if (!empty($list)) {
|
||||
$defaults[$key] = $list;
|
||||
}
|
||||
} else {
|
||||
// We hit a field; get default from it if it exists.
|
||||
$item = $this->get($value);
|
||||
|
||||
// Only return default value if it exists.
|
||||
if (isset($item['default'])) {
|
||||
$defaults[$key] = $item['default'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data1
|
||||
* @param array $data2
|
||||
* @param array $rules
|
||||
* @return array
|
||||
* @internal
|
||||
*/
|
||||
protected function mergeArrays(array $data1, array $data2, array $rules)
|
||||
{
|
||||
foreach ($data2 as $key => $field) {
|
||||
$val = isset($rules[$key]) ? $rules[$key] : null;
|
||||
$rule = is_string($val) ? $this->items[$val] : null;
|
||||
|
||||
if ($rule && $rule['type'] === '_parent' || (array_key_exists($key, $data1) && is_array($data1[$key]) && is_array($field) && is_array($val) && !isset($val['*']))) {
|
||||
// Array has been defined in blueprints and is not a collection of items.
|
||||
$data1[$key] = $this->mergeArrays($data1[$key], $field, $val);
|
||||
} else {
|
||||
// Otherwise just take value from the data2.
|
||||
$data1[$key] = $field;
|
||||
}
|
||||
}
|
||||
|
||||
return $data1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all field definitions from the blueprints.
|
||||
*
|
||||
* @param array $fields
|
||||
* @param array $params
|
||||
* @param string $prefix
|
||||
* @param string $parent
|
||||
* @internal
|
||||
*/
|
||||
protected function parseFormFields(array &$fields, array $params, $prefix = '', $parent = '')
|
||||
{
|
||||
// Go though all the fields in current level.
|
||||
foreach ($fields as $key => &$field) {
|
||||
// Set name from the array key.
|
||||
if ($key && $key[0] == '.') {
|
||||
$key = ($parent ?: rtrim($prefix, '.')) . $key;
|
||||
} else {
|
||||
$key = $prefix . $key;
|
||||
}
|
||||
$field['name'] = $key;
|
||||
$field += $params;
|
||||
|
||||
if (isset($field['fields'])) {
|
||||
$isArray = !empty($field['array']);
|
||||
|
||||
// Recursively get all the nested fields.
|
||||
$newParams = array_intersect_key($this->filter, $field);
|
||||
$this->parseFormFields($field['fields'], $newParams, $prefix, $key . ($isArray ? '.*': ''));
|
||||
} else {
|
||||
// Add rule.
|
||||
$path = explode('.', $key);
|
||||
array_pop($path);
|
||||
$parent = '';
|
||||
foreach ($path as $part) {
|
||||
$parent .= ($parent ? '.' : '') . $part;
|
||||
if (!isset($this->items[$parent])) {
|
||||
$this->items[$parent] = ['type' => '_parent', 'name' => $parent];
|
||||
}
|
||||
}
|
||||
$this->items[$key] = &$field;
|
||||
$this->addProperty($key);
|
||||
|
||||
foreach ($field as $name => $value) {
|
||||
if (substr($name, 0, 6) == '@data-') {
|
||||
$property = substr($name, 6);
|
||||
if (is_array($value)) {
|
||||
$func = array_shift($value);
|
||||
} else {
|
||||
$func = $value;
|
||||
$value = array();
|
||||
}
|
||||
list($o, $f) = preg_split('/::/', $func);
|
||||
if (!$f && function_exists($o)) {
|
||||
$data = call_user_func_array($o, $value);
|
||||
} elseif ($f && method_exists($o, $f)) {
|
||||
$data = call_user_func_array(array($o, $f), $value);
|
||||
}
|
||||
|
||||
// If function returns a value,
|
||||
if (isset($data)) {
|
||||
if (isset($field[$property]) && is_array($field[$property]) && is_array($data)) {
|
||||
// Combine field and @data-field together.
|
||||
$field[$property] += $data;
|
||||
} else {
|
||||
// Or create/replace field with @data-field.
|
||||
$field[$property] = $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize predefined validation rule.
|
||||
if (isset($field['validate']['rule'])) {
|
||||
$field['validate'] += $this->getRule($field['validate']['rule']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get property from the definition.
|
||||
*
|
||||
* @param string $path Comma separated path to the property.
|
||||
* @param string $separator
|
||||
* @return array
|
||||
* @internal
|
||||
*/
|
||||
public function getProperty($path = null, $separator = '.')
|
||||
{
|
||||
if (!$path) {
|
||||
return $this->nested;
|
||||
}
|
||||
$parts = explode($separator, $path);
|
||||
$item = array_pop($parts);
|
||||
|
||||
$nested = $this->nested;
|
||||
foreach ($parts as $part) {
|
||||
if (!isset($nested[$part])) {
|
||||
return [];
|
||||
}
|
||||
$nested = $nested[$part];
|
||||
}
|
||||
|
||||
return isset($nested[$item]) ? $nested[$item] : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add property to the definition.
|
||||
*
|
||||
* @param string $path Comma separated path to the property.
|
||||
* @internal
|
||||
*/
|
||||
protected function addProperty($path)
|
||||
{
|
||||
$parts = explode('.', $path);
|
||||
$item = array_pop($parts);
|
||||
|
||||
$nested = &$this->nested;
|
||||
foreach ($parts as $part) {
|
||||
if (!isset($nested[$part])) {
|
||||
$nested[$part] = array();
|
||||
}
|
||||
$nested = &$nested[$part];
|
||||
}
|
||||
|
||||
if (!isset($nested[$item])) {
|
||||
$nested[$item] = $path;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $rule
|
||||
* @return array
|
||||
* @internal
|
||||
*/
|
||||
protected function getRule($rule)
|
||||
{
|
||||
if (isset($this->rules[$rule]) && is_array($this->rules[$rule])) {
|
||||
return $this->rules[$rule];
|
||||
}
|
||||
return array();
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
# v1.1.4
|
||||
## 10/15/2015
|
||||
|
||||
1. [](#new)
|
||||
* Add support for native YAML parsing option to Markdown and YAML file classes
|
||||
|
||||
# v1.1.3
|
||||
## 10/13/2015
|
||||
|
||||
3. [](#bugfix)
|
||||
* Fix regression: Default values for collections were broken
|
||||
* Fix Argument 1 passed to `RocketTheme\Toolbox\Blueprints\Blueprints::mergeArrays()` must be of the type array
|
||||
* Add exception on Blueprint collection merging; only overridden value should be used
|
||||
* File locking truncates contents of the file
|
||||
* Stop duplicate Messages getting added to the queue
|
||||
|
||||
# v1.1.2
|
||||
## 08/27/2015
|
||||
|
||||
1. [](#new)
|
||||
* Creation of Changelog
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\DI;
|
||||
|
||||
use Pimple\Container as BaseContainer;
|
||||
|
||||
/**
|
||||
* Implements Dependency Injection Container.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\DI
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Container extends BaseContainer
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\DI;
|
||||
|
||||
use \Pimple\ServiceProviderInterface as BaseServiceProviderInterface;
|
||||
|
||||
/**
|
||||
* Defines ServiceProviderInterface.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\DI
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
interface ServiceProviderInterface extends BaseServiceProviderInterface
|
||||
{
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\Event;
|
||||
|
||||
use RocketTheme\Toolbox\ArrayTraits\ArrayAccess;
|
||||
use RocketTheme\Toolbox\ArrayTraits\Constructor;
|
||||
use Symfony\Component\EventDispatcher\Event as BaseEvent;
|
||||
|
||||
/**
|
||||
* Implements Symfony Event interface.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\Event
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Event extends BaseEvent implements \ArrayAccess
|
||||
{
|
||||
use ArrayAccess, Constructor;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $items = array();
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\Event;
|
||||
|
||||
use Symfony\Component\EventDispatcher\Event as BaseEvent;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher as BaseEventDispatcher;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
|
||||
/**
|
||||
* Implements Symfony EventDispatcher interface.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\Event
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class EventDispatcher extends BaseEventDispatcher implements EventDispatcherInterface
|
||||
{
|
||||
public function dispatch($eventName, BaseEvent $event = null)
|
||||
{
|
||||
if (null === $event) {
|
||||
$event = new Event();
|
||||
}
|
||||
|
||||
return parent::dispatch($eventName, $event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\Event;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface as BaseEventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* Defines EventSubscriberInterface.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\Event
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
interface EventSubscriberInterface extends BaseEventSubscriberInterface
|
||||
{
|
||||
}
|
||||
+420
@@ -0,0 +1,420 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\File;
|
||||
|
||||
/**
|
||||
* Implements Universal File Reader.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\File
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class File implements FileInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $filename;
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
protected $handle;
|
||||
|
||||
/**
|
||||
* @var bool|null
|
||||
*/
|
||||
protected $locked;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $extension;
|
||||
|
||||
/**
|
||||
* @var string Raw file contents.
|
||||
*/
|
||||
protected $raw;
|
||||
|
||||
/**
|
||||
* @var array Parsed file contents.
|
||||
*/
|
||||
protected $content;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $settings = [];
|
||||
|
||||
/**
|
||||
* @var array|File[]
|
||||
*/
|
||||
static protected $instances = array();
|
||||
|
||||
/**
|
||||
* Get file instance.
|
||||
*
|
||||
* @param string $filename
|
||||
* @return FileInterface
|
||||
*/
|
||||
public static function instance($filename)
|
||||
{
|
||||
if (!is_string($filename) && $filename) {
|
||||
throw new \InvalidArgumentException('Filename should be non-empty string');
|
||||
}
|
||||
if (!isset(static::$instances[$filename])) {
|
||||
static::$instances[$filename] = new static;
|
||||
static::$instances[$filename]->init($filename);
|
||||
}
|
||||
return static::$instances[$filename];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set/get settings.
|
||||
*
|
||||
* @param array $settings
|
||||
* @return array
|
||||
*/
|
||||
public function settings(array $settings = null)
|
||||
{
|
||||
if ($settings !== null) {
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
return $this->settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get setting.
|
||||
*
|
||||
* @param string $setting
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function setting($setting, $default = null)
|
||||
{
|
||||
return isset($this->settings[$setting]) ? $this->settings[$setting] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent constructor from being used.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent cloning.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
protected function __clone()
|
||||
{
|
||||
//Me not like clones! Me smash clones!
|
||||
}
|
||||
|
||||
/**
|
||||
* Set filename.
|
||||
*
|
||||
* @param $filename
|
||||
*/
|
||||
protected function init($filename)
|
||||
{
|
||||
$this->filename = $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free the file instance.
|
||||
*/
|
||||
public function free()
|
||||
{
|
||||
if ($this->locked) {
|
||||
$this->unlock();
|
||||
}
|
||||
$this->content = null;
|
||||
$this->raw = null;
|
||||
|
||||
unset(static::$instances[$this->filename]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get/set the file location.
|
||||
*
|
||||
* @param string $var
|
||||
* @return string
|
||||
*/
|
||||
public function filename($var = null)
|
||||
{
|
||||
if ($var !== null) {
|
||||
$this->filename = $var;
|
||||
}
|
||||
return $this->filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return basename of the file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function basename()
|
||||
{
|
||||
return basename($this->filename, $this->extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if file exits.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function exists()
|
||||
{
|
||||
return is_file($this->filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return file modification time.
|
||||
*
|
||||
* @return int|bool Timestamp or false if file doesn't exist.
|
||||
*/
|
||||
public function modified()
|
||||
{
|
||||
return is_file($this->filename) ? filemtime($this->filename) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lock file for writing. You need to manually unlock().
|
||||
*
|
||||
* @param bool $block For non-blocking lock, set the parameter to false.
|
||||
* @return bool
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function lock($block = true)
|
||||
{
|
||||
if (!$this->handle) {
|
||||
if (!$this->mkdir(dirname($this->filename))) {
|
||||
throw new \RuntimeException('Creating directory failed for ' . $this->filename);
|
||||
}
|
||||
$this->handle = @fopen($this->filename, 'cb+');
|
||||
if (!$this->handle) {
|
||||
$error = error_get_last();
|
||||
|
||||
throw new \RuntimeException("Opening file for writing failed on error {$error['message']}");
|
||||
}
|
||||
}
|
||||
$lock = $block ? LOCK_EX : LOCK_EX | LOCK_NB;
|
||||
return $this->locked = $this->handle ? flock($this->handle, $lock) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if file has been locked for writing.
|
||||
*
|
||||
* @return bool|null True = locked, false = failed, null = not locked.
|
||||
*/
|
||||
public function locked()
|
||||
{
|
||||
return $this->locked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock file.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function unlock()
|
||||
{
|
||||
if (!$this->handle) {
|
||||
return;
|
||||
}
|
||||
if ($this->locked) {
|
||||
flock($this->handle, LOCK_UN);
|
||||
$this->locked = null;
|
||||
}
|
||||
fclose($this->handle);
|
||||
$this->handle = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if file can be written.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function writable()
|
||||
{
|
||||
return is_writable($this->filename) || $this->writableDir(dirname($this->filename));
|
||||
}
|
||||
|
||||
/**
|
||||
* (Re)Load a file and return RAW file contents.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function load()
|
||||
{
|
||||
$this->raw = $this->exists() ? (string) file_get_contents($this->filename) : '';
|
||||
$this->content = null;
|
||||
|
||||
return $this->raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get/set raw file contents.
|
||||
*
|
||||
* @param string $var
|
||||
* @return string
|
||||
*/
|
||||
public function raw($var = null)
|
||||
{
|
||||
if ($var !== null) {
|
||||
$this->raw = (string) $var;
|
||||
$this->content = null;
|
||||
}
|
||||
|
||||
if (!is_string($this->raw)) {
|
||||
$this->raw = $this->load();
|
||||
}
|
||||
|
||||
return $this->raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get/set parsed file contents.
|
||||
*
|
||||
* @param mixed $var
|
||||
* @return string|array
|
||||
*/
|
||||
public function content($var = null)
|
||||
{
|
||||
if ($var !== null) {
|
||||
$this->content = $this->check($var);
|
||||
|
||||
// Update RAW, too.
|
||||
$this->raw = $this->encode($this->content);
|
||||
|
||||
} elseif ($this->content === null) {
|
||||
// Decode RAW file.
|
||||
$this->content = $this->decode($this->raw());
|
||||
}
|
||||
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save file.
|
||||
*
|
||||
* @param mixed $data Optional data to be saved, usually array.
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function save($data = null)
|
||||
{
|
||||
if ($data !== null) {
|
||||
$this->content($data);
|
||||
}
|
||||
|
||||
if (!$this->locked) {
|
||||
// Obtain blocking lock or fail.
|
||||
if (!$this->lock()) {
|
||||
throw new \RuntimeException('Obtaining write lock failed on file: ' . $this->filename);
|
||||
}
|
||||
$lock = true;
|
||||
}
|
||||
|
||||
// As we are using non-truncating locking, make sure that the file is empty before writing.
|
||||
if (@ftruncate($this->handle, 0) === false || @fwrite($this->handle, $this->raw()) === false) {
|
||||
$this->unlock();
|
||||
throw new \RuntimeException('Saving file failed: ' . $this->filename);
|
||||
}
|
||||
|
||||
if (isset($lock)) {
|
||||
$this->unlock();
|
||||
}
|
||||
|
||||
// Touch the directory as well, thus marking it modified.
|
||||
@touch(dirname($this->filename));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete file from filesystem.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
return unlink($this->filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check contents and make sure it is in correct format.
|
||||
*
|
||||
* Override in derived class.
|
||||
*
|
||||
* @param string $var
|
||||
* @return string
|
||||
*/
|
||||
protected function check($var)
|
||||
{
|
||||
return (string) $var;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode contents into RAW string.
|
||||
*
|
||||
* Override in derived class.
|
||||
*
|
||||
* @param string $var
|
||||
* @return string
|
||||
*/
|
||||
protected function encode($var)
|
||||
{
|
||||
return (string) $var;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode RAW string into contents.
|
||||
*
|
||||
* Override in derived class.
|
||||
*
|
||||
* @param string $var
|
||||
* @return string mixed
|
||||
*/
|
||||
protected function decode($var)
|
||||
{
|
||||
return (string) $var;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $dir
|
||||
* @return bool
|
||||
* @throws \RuntimeException
|
||||
* @internal
|
||||
*/
|
||||
protected function mkdir($dir)
|
||||
{
|
||||
// Silence error for open_basedir; should fail in mkdir instead.
|
||||
if (!@is_dir($dir)) {
|
||||
$success = @mkdir($dir, 0777, true);
|
||||
|
||||
if (!$success) {
|
||||
$error = error_get_last();
|
||||
|
||||
throw new \RuntimeException("Creating directory '{$dir}' failed on error {$error['message']}");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $dir
|
||||
* @return bool
|
||||
* @internal
|
||||
*/
|
||||
protected function writableDir($dir)
|
||||
{
|
||||
if ($dir && !file_exists($dir)) {
|
||||
return $this->writableDir(dirname($dir));
|
||||
}
|
||||
|
||||
return $dir && is_dir($dir) && is_writable($dir);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\File;
|
||||
|
||||
/**
|
||||
* Defines FileInterface.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\File
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
interface FileInterface
|
||||
{
|
||||
/**
|
||||
* Get file instance.
|
||||
*
|
||||
* @param string $filename
|
||||
* @return mixed
|
||||
*/
|
||||
public static function instance($filename);
|
||||
|
||||
/**
|
||||
* Free the file instance.
|
||||
*/
|
||||
public function free();
|
||||
|
||||
/**
|
||||
* Check if file exits.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function exists();
|
||||
|
||||
/**
|
||||
* Return file modification time.
|
||||
*
|
||||
* @return int Timestamp
|
||||
*/
|
||||
public function modified();
|
||||
|
||||
/**
|
||||
* Lock file for writing. Lock gets automatically released during the save().
|
||||
*
|
||||
* @param bool $block For non-blocking lock, set the parameter to false.
|
||||
* @return bool
|
||||
*/
|
||||
public function lock($block = true);
|
||||
|
||||
/**
|
||||
* Returns true if file has been locked for writing.
|
||||
*
|
||||
* @return bool|null True = locked, false = failed, null = not locked.
|
||||
*/
|
||||
public function locked();
|
||||
|
||||
/**
|
||||
* Unlock file.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function unlock();
|
||||
|
||||
/**
|
||||
* Check if file can be written.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function writable();
|
||||
|
||||
/**
|
||||
* (Re)Load a file and return its contents.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function load();
|
||||
|
||||
/**
|
||||
* Get/set raw file contents.
|
||||
*
|
||||
* @param string $var
|
||||
* @return string
|
||||
*/
|
||||
public function raw($var = null);
|
||||
|
||||
/**
|
||||
* Get/set parsed file contents.
|
||||
*
|
||||
* @param string $var
|
||||
* @return string
|
||||
*/
|
||||
public function content($var = null);
|
||||
|
||||
/**
|
||||
* Save file.
|
||||
*
|
||||
* @param string $data Optional data to be saved.
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function save($data = null);
|
||||
|
||||
/**
|
||||
* Delete file from filesystem.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete();
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\File;
|
||||
|
||||
/**
|
||||
* Implements INI File reader.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\File
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class IniFile extends File
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $extension = '.ini';
|
||||
|
||||
/**
|
||||
* @var array|File[]
|
||||
*/
|
||||
static protected $instances = array();
|
||||
|
||||
/**
|
||||
* Check contents and make sure it is in correct format.
|
||||
*
|
||||
* @param array $var
|
||||
* @return array
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function check($var)
|
||||
{
|
||||
if (!is_array($var)) {
|
||||
throw new \RuntimeException('Provided data is not an array');
|
||||
}
|
||||
|
||||
return $var;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode configuration object into RAW string (INI).
|
||||
*
|
||||
* @param array $var
|
||||
* @return string
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function encode($var)
|
||||
{
|
||||
$string = '';
|
||||
foreach ($var as $key => $value) {
|
||||
$string .= $key . '="' . preg_replace(
|
||||
['/"/', '/\\\/', "/\t/", "/\n/", "/\r/"],
|
||||
['\"', '\\\\', '\t', '\n', '\r'],
|
||||
$value
|
||||
) . "\"\n";
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode INI file into contents.
|
||||
*
|
||||
* @param string $var
|
||||
* @return array
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function decode($var)
|
||||
{
|
||||
$var = @parse_ini_file($this->filename);
|
||||
|
||||
if ($var === false) {
|
||||
throw new \RuntimeException("Decoding file '{$this->filename}' failed'");
|
||||
}
|
||||
|
||||
return $var;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\File;
|
||||
|
||||
/**
|
||||
* Implements Json File reader.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\File
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class JsonFile extends File
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $extension = '.json';
|
||||
|
||||
/**
|
||||
* @var array|File[]
|
||||
*/
|
||||
static protected $instances = array();
|
||||
|
||||
/**
|
||||
* Check contents and make sure it is in correct format.
|
||||
*
|
||||
* @param array $var
|
||||
* @return array
|
||||
*/
|
||||
protected function check($var)
|
||||
{
|
||||
return (array) $var;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode contents into RAW string.
|
||||
*
|
||||
* @param string $var
|
||||
* @params bitmask $options
|
||||
* @return string
|
||||
*/
|
||||
protected function encode($var, $options = 0)
|
||||
{
|
||||
return (string) json_encode($var, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode RAW string into contents.
|
||||
*
|
||||
* @param string $var
|
||||
* @param bool $assoc
|
||||
* @return array mixed
|
||||
*/
|
||||
protected function decode($var, $assoc = false)
|
||||
{
|
||||
return (array) json_decode($var, $assoc);
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\File;
|
||||
|
||||
/**
|
||||
* Implements Log File reader.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\File
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class LogFile extends File
|
||||
{
|
||||
/**
|
||||
* @var array|File[]
|
||||
*/
|
||||
static protected $instances = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->extension = '.log';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check contents and make sure it is in correct format.
|
||||
*
|
||||
* @param array $var
|
||||
* @return array
|
||||
*/
|
||||
protected function check($var)
|
||||
{
|
||||
return (array) $var;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode contents into RAW string (unsupported).
|
||||
*
|
||||
* @param string $var
|
||||
* @return string|void
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function encode($var)
|
||||
{
|
||||
throw new \Exception('Saving log file is forbidden.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode RAW string into contents.
|
||||
*
|
||||
* @param string $var
|
||||
* @return array mixed
|
||||
*/
|
||||
protected function decode($var)
|
||||
{
|
||||
$lines = (array) preg_split('#(\r\n|\n|\r)#', $var);
|
||||
|
||||
$results = array();
|
||||
foreach ($lines as $line) {
|
||||
preg_match('#^\[(.*)\] (.*) @ (.*) @@ (.*)$#', $line, $matches);
|
||||
if ($matches) {
|
||||
$results[] = ['date' => $matches[1], 'message' => $matches[2], 'url' => $matches[3], 'file' => $matches[4]];
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\File;
|
||||
|
||||
use \Symfony\Component\Yaml\Yaml as YamlParser;
|
||||
|
||||
/**
|
||||
* Implements Markdown File reader.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\File
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class MarkdownFile extends File
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $extension = '.md';
|
||||
|
||||
/**
|
||||
* @var array|File[]
|
||||
*/
|
||||
static protected $instances = array();
|
||||
|
||||
/**
|
||||
* Get/set file header.
|
||||
*
|
||||
* @param array $var
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function header(array $var = null)
|
||||
{
|
||||
$content = $this->content();
|
||||
|
||||
if ($var !== null) {
|
||||
$content['header'] = $var;
|
||||
$this->content($content);
|
||||
}
|
||||
|
||||
return $content['header'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get/set markdown content.
|
||||
*
|
||||
* @param string $var
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function markdown($var = null)
|
||||
{
|
||||
$content = $this->content();
|
||||
|
||||
if ($var !== null) {
|
||||
$content['markdown'] = (string) $var;
|
||||
$this->content($content);
|
||||
}
|
||||
|
||||
return $content['markdown'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get/set frontmatter content.
|
||||
*
|
||||
* @param string $var
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function frontmatter($var = null)
|
||||
{
|
||||
$content = $this->content();
|
||||
|
||||
if ($var !== null) {
|
||||
$content['frontmatter'] = (string) $var;
|
||||
$this->content($content);
|
||||
}
|
||||
|
||||
return $content['frontmatter'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check contents and make sure it is in correct format.
|
||||
*
|
||||
* @param array $var
|
||||
* @return array
|
||||
*/
|
||||
protected function check($var)
|
||||
{
|
||||
$var = (array) $var;
|
||||
if (!isset($var['header']) || !is_array($var['header'])) {
|
||||
$var['header'] = array();
|
||||
}
|
||||
if (!isset($var['markdown']) || !is_string($var['markdown'])) {
|
||||
$var['markdown'] = '';
|
||||
}
|
||||
|
||||
return $var;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode contents into RAW string.
|
||||
*
|
||||
* @param string $var
|
||||
* @return string
|
||||
*/
|
||||
protected function encode($var)
|
||||
{
|
||||
// Create Markdown file with YAML header.
|
||||
$o = (!empty($var['header']) ? "---\n" . trim(YamlParser::dump($var['header'], 5)) . "\n---\n\n" : '') . $var['markdown'];
|
||||
|
||||
// Normalize line endings to Unix style.
|
||||
$o = preg_replace("/(\r\n|\r)/", "\n", $o);
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode RAW string into contents.
|
||||
*
|
||||
* @param string $var
|
||||
* @return array mixed
|
||||
*/
|
||||
protected function decode($var)
|
||||
{
|
||||
$content = [
|
||||
'header' => false,
|
||||
'frontmatter' => ''
|
||||
];
|
||||
|
||||
$frontmatter_regex = "/^---\n(.+?)\n---\n{0,}(.*)$/uis";
|
||||
|
||||
// Normalize line endings to Unix style.
|
||||
$var = preg_replace("/(\r\n|\r)/", "\n", $var);
|
||||
|
||||
// Parse header.
|
||||
preg_match($frontmatter_regex, ltrim($var), $m);
|
||||
if(!empty($m)) {
|
||||
$content['frontmatter'] = preg_replace("/\n\t/", "\n ", $m[1]);
|
||||
|
||||
// Try native PECL YAML PHP extension first if available.
|
||||
if ($this->setting('native') && function_exists('yaml_parse')) {
|
||||
$data = $content['frontmatter'];
|
||||
if ($this->setting('compat', true)) {
|
||||
// Fix illegal @ start character.
|
||||
$data = preg_replace('/ (@[\w\.\-]*)/', " '\${1}'", $data);
|
||||
}
|
||||
|
||||
// Safely decode YAML.
|
||||
$saved = @ini_get('yaml.decode_php');
|
||||
@ini_set('yaml.decode_php', 0);
|
||||
$content['header'] = @yaml_parse("---\n" . $data . "\n...");
|
||||
@ini_set('yaml.decode_php', $saved);
|
||||
}
|
||||
|
||||
if ($content['header'] === false) {
|
||||
// YAML hasn't been parsed yet (error or extension isn't available). Fall back to Symfony parser.
|
||||
$content['header'] = (array) YamlParser::parse($content['frontmatter']);
|
||||
}
|
||||
$content['markdown'] = $m[2];
|
||||
} else {
|
||||
$content['header'] = [];
|
||||
$content['markdown'] = $var;
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\File;
|
||||
|
||||
/**
|
||||
* Implements Gettext Mo File reader (readonly).
|
||||
*
|
||||
* @package RocketTheme\Toolbox\File
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class MoFile extends File
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $extension = '.mo';
|
||||
|
||||
protected $pos = 0;
|
||||
protected $str;
|
||||
protected $len;
|
||||
protected $endian;
|
||||
|
||||
/**
|
||||
* @var array|File[]
|
||||
*/
|
||||
static protected $instances = array();
|
||||
|
||||
/**
|
||||
* File can never be written.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function writable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent saving file.
|
||||
*
|
||||
* @throws \BadMethodCallException
|
||||
*/
|
||||
public function save($data = null)
|
||||
{
|
||||
throw new \BadMethodCallException('save() not supported for .mo files.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent deleting file from filesystem.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $var
|
||||
* @return array
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function decode($var)
|
||||
{
|
||||
$this->endian = 'V';
|
||||
$this->str = $var;
|
||||
$this->len = strlen($var);
|
||||
|
||||
$magic = $this->readInt() & 0xffffffff;
|
||||
|
||||
if ($magic === 0x950412de) {
|
||||
// Low endian.
|
||||
$this->endian = 'V';
|
||||
} elseif ($magic === 0xde120495) {
|
||||
// Big endian.
|
||||
$this->endian = 'N';
|
||||
} else {
|
||||
throw new \RuntimeException('Not a Gettext file (.mo).');
|
||||
}
|
||||
|
||||
// Skip revision number.
|
||||
$rev = $this->readInt();
|
||||
// Total count.
|
||||
$total = $this->readInt();
|
||||
// Offset of original table.
|
||||
$originals = $this->readInt();
|
||||
// Offset of translation table.
|
||||
$translations = $this->readInt();
|
||||
|
||||
// Each table consists of string length and offset of the string.
|
||||
$this->seek($originals);
|
||||
$table_originals = $this->readIntArray($total * 2);
|
||||
$this->seek($translations);
|
||||
$table_translations = $this->readIntArray($total * 2);
|
||||
|
||||
$items = [];
|
||||
for ($i = 0; $i < $total; $i++) {
|
||||
$this->seek($table_originals[$i * 2 + 2]);
|
||||
|
||||
// TODO: Original string can have context concatenated on it. We do not yet support that.
|
||||
$original = $this->read($table_originals[$i * 2 + 1]);
|
||||
|
||||
if ($original) {
|
||||
$this->seek($table_translations[$i * 2 + 2]);
|
||||
|
||||
// TODO: Plural forms are stored by letting the plural of the original string follow the singular of the original string, separated through a NUL byte.
|
||||
$translated = $this->read($table_translations[$i * 2 + 1]);
|
||||
$items[$original] = $translated;
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
protected function readInt()
|
||||
{
|
||||
$read = $this->read(4);
|
||||
|
||||
if ($read === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$read = unpack($this->endian, $read);
|
||||
|
||||
return array_shift($read);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $count
|
||||
* @return array
|
||||
*/
|
||||
protected function readIntArray($count)
|
||||
{
|
||||
return unpack($this->endian . $count, $this->read(4 * $count));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $bytes
|
||||
* @return string
|
||||
*/
|
||||
private function read($bytes)
|
||||
{
|
||||
$data = substr($this->str, $this->pos, $bytes);
|
||||
$this->seek($this->pos + $bytes);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $pos
|
||||
* @return mixed
|
||||
*/
|
||||
private function seek($pos)
|
||||
{
|
||||
$this->pos = $pos < $this->len ? $pos : $this->len;
|
||||
return $this->pos;
|
||||
}
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\File;
|
||||
|
||||
/**
|
||||
* Implements PHP File reader.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\File
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class PhpFile extends File
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $extension = '.php';
|
||||
|
||||
/**
|
||||
* @var array|File[]
|
||||
*/
|
||||
static protected $instances = array();
|
||||
|
||||
/**
|
||||
* Saves PHP file and invalidates opcache.
|
||||
*
|
||||
* @param mixed $data Optional data to be saved, usually array.
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function save($data = null)
|
||||
{
|
||||
parent::save($data);
|
||||
|
||||
// Invalidate configuration file from the opcache.
|
||||
if (function_exists('opcache_invalidate')) {
|
||||
// PHP 5.5.5+
|
||||
@opcache_invalidate($this->filename);
|
||||
} elseif (function_exists('apc_invalidate')) {
|
||||
// APC
|
||||
@apc_invalidate($this->filename);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check contents and make sure it is in correct format.
|
||||
*
|
||||
* @param array $var
|
||||
* @return array
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function check($var)
|
||||
{
|
||||
if (!(is_array($var) || is_object($var))) {
|
||||
throw new \RuntimeException('Provided data is not an array');
|
||||
}
|
||||
|
||||
return $var;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode configuration object into RAW string (PHP class).
|
||||
*
|
||||
* @param array $var
|
||||
* @return string
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function encode($var)
|
||||
{
|
||||
// Build the object variables string
|
||||
return "<?php\nreturn {$this->encodeArray((array) $var)};\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get an array as an exported string.
|
||||
*
|
||||
* @param array $a The array to get as a string.
|
||||
* @param int $level Used internally to indent rows.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function encodeArray(array $a, $level = 0)
|
||||
{
|
||||
$r = [];
|
||||
foreach ($a as $k => $v) {
|
||||
if (is_array($v) || is_object($v)) {
|
||||
$r[] = var_export($k, true) . " => " . $this->encodeArray((array) $v, $level + 1);
|
||||
} else {
|
||||
$r[] = var_export($k, true) . " => " . var_export($v, true);
|
||||
}
|
||||
}
|
||||
|
||||
$space = str_repeat(" ", $level);
|
||||
return "[\n {$space}" . implode(",\n {$space}", $r) . "\n{$space}]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode PHP file into contents.
|
||||
*
|
||||
* @param string $var
|
||||
* @return array
|
||||
*/
|
||||
protected function decode($var)
|
||||
{
|
||||
$var = (array) include $this->filename;
|
||||
return $var;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\File;
|
||||
|
||||
use Symfony\Component\Yaml\Exception\DumpException;
|
||||
use Symfony\Component\Yaml\Exception\ParseException;
|
||||
use \Symfony\Component\Yaml\Yaml as YamlParser;
|
||||
|
||||
/**
|
||||
* Implements YAML File reader.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\File
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class YamlFile extends File
|
||||
{
|
||||
/**
|
||||
* @var array|File[]
|
||||
*/
|
||||
static protected $instances = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->extension = '.yaml';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check contents and make sure it is in correct format.
|
||||
*
|
||||
* @param array $var
|
||||
* @return array
|
||||
*/
|
||||
protected function check($var)
|
||||
{
|
||||
return (array) $var;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode contents into RAW string.
|
||||
*
|
||||
* @param string $var
|
||||
* @return string
|
||||
* @throws DumpException
|
||||
*/
|
||||
protected function encode($var)
|
||||
{
|
||||
return (string) YamlParser::dump($var, $this->setting('inline', 5), $this->setting('indent', 2), true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode RAW string into contents.
|
||||
*
|
||||
* @param string $var
|
||||
* @return array mixed
|
||||
* @throws ParseException
|
||||
*/
|
||||
protected function decode($var)
|
||||
{
|
||||
$data = false;
|
||||
|
||||
// Try native PECL YAML PHP extension first if available.
|
||||
if ($this->setting('native') && function_exists('yaml_parse')) {
|
||||
if ($this->setting('compat', true)) {
|
||||
// Fix illegal @ start character.
|
||||
$data = preg_replace('/ (@[\w\.\-]*)/', " '\${1}'", $var);
|
||||
} else {
|
||||
$data = $var;
|
||||
}
|
||||
|
||||
// Safely decode YAML.
|
||||
$saved = @ini_get('yaml.decode_php');
|
||||
@ini_set('yaml.decode_php', 0);
|
||||
$data = @yaml_parse("---\n" . $data . "\n...");
|
||||
@ini_set('yaml.decode_php', $saved);
|
||||
}
|
||||
|
||||
return $data !== false ? $data : (array) YamlParser::parse($var);
|
||||
}
|
||||
}
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 RocketTheme
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
Vendored
+56
@@ -0,0 +1,56 @@
|
||||
#  RocketTheme Toolbox
|
||||
|
||||
[](https://packagist.org/packages/rockettheme/toolbox)
|
||||
[](LICENSE)
|
||||
[](https://travis-ci.org/rockettheme/toolbox)
|
||||
[](https://scrutinizer-ci.com/g/rockettheme/toolbox/code-structure)
|
||||
[](https://scrutinizer-ci.com/g/rockettheme/toolbox)
|
||||
[](https://packagist.org/packages/rockettheme/toolbox)
|
||||
|
||||
RocketTheme\Toolbox package contains a set of reusable PHP interfaces, classes and traits.
|
||||
|
||||
* ArrayTraits
|
||||
* DI
|
||||
* Event
|
||||
* File
|
||||
* ResourceLocator
|
||||
* Session
|
||||
* StreamWrapper
|
||||
|
||||
## Installation
|
||||
|
||||
You can use [Composer](http://getcomposer.org/) to download and install this package as well as its dependencies.
|
||||
|
||||
### Composer
|
||||
|
||||
To add this package as a local, per-project dependency to your project, simply add a dependency on `rockettheme/toolbox` to your project's `composer.json` file. Here is a minimal example of a `composer.json` file that just defines a dependency on Diff:
|
||||
|
||||
{
|
||||
"require": {
|
||||
"rockettheme/toolbox": "dev-master"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Contributing
|
||||
|
||||
We appreciate any contribution to ToolBox, whether it is related to bugs or simply a suggestion or improvement.
|
||||
However, we ask that any contribution follow our simple guidelines in order to be properly received.
|
||||
|
||||
All our projects follow the [GitFlow branching model][gitflow-model], from development to release. If you are not familiar with it, there are several guides and tutorials to make you understand what it is about.
|
||||
|
||||
You will probably want to get started by installing [this very good collection of git extensions][gitflow-extensions].
|
||||
|
||||
What you mainly want to know is that:
|
||||
|
||||
- All the main activity happens in the `develop` branch. Any pull request should be addressed only to that branch. We will not consider pull requests made to the `master`.
|
||||
- It's very well appreciated, and highly suggested, to start a new feature whenever you want to make changes or add functionalities. It will make it much easier for us to just checkout your feature branch and test it, before merging it into `develop`
|
||||
|
||||
|
||||
# Getting Started
|
||||
|
||||
* Have fun!!!
|
||||
|
||||
|
||||
[gitflow-model]: http://nvie.com/posts/a-successful-git-branching-model/
|
||||
[gitflow-extensions]: https://github.com/nvie/gitflow
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\ResourceLocator;
|
||||
|
||||
/**
|
||||
* Implements recursive iterator over filesystem.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\ResourceLocator
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class RecursiveUniformResourceIterator extends UniformResourceIterator implements \RecursiveIterator
|
||||
{
|
||||
protected $subPath;
|
||||
|
||||
public function getChildren()
|
||||
{
|
||||
$subPath = $this->getSubPathName();
|
||||
|
||||
return (new RecursiveUniformResourceIterator($this->getUrl(), $this->flags, $this->locator))->setSubPath($subPath);
|
||||
}
|
||||
|
||||
public function hasChildren($allow_links = false)
|
||||
{
|
||||
return $this->iterator && $this->isDir() && !$this->isDot() && ($allow_links || !$this->isLink());
|
||||
}
|
||||
|
||||
public function getSubPath()
|
||||
{
|
||||
return $this->subPath;
|
||||
}
|
||||
|
||||
public function getSubPathName()
|
||||
{
|
||||
return ($this->subPath ? $this->subPath . '/' : '') . $this->getFilename();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $path
|
||||
* @return $this
|
||||
* @internal
|
||||
*/
|
||||
public function setSubPath($path)
|
||||
{
|
||||
$this->subPath = $path;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace RocketTheme\Toolbox\ResourceLocator;
|
||||
|
||||
/**
|
||||
* Defines ResourceLocatorInterface.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\ResourceLocator
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
interface ResourceLocatorInterface
|
||||
{
|
||||
/**
|
||||
* Alias for findResource()
|
||||
*
|
||||
* @param $uri
|
||||
* @return string|bool
|
||||
*/
|
||||
public function __invoke($uri);
|
||||
|
||||
/**
|
||||
* @param string $uri
|
||||
* @param bool $absolute
|
||||
* @param bool $first
|
||||
* @return string|bool
|
||||
*/
|
||||
public function findResource($uri, $absolute = true, $first = false);
|
||||
|
||||
/**
|
||||
* @param string $uri
|
||||
* @param bool $absolute
|
||||
* @param bool $all
|
||||
* @return array
|
||||
*/
|
||||
public function findResources($uri, $absolute = true, $all = false);
|
||||
}
|
||||
@@ -0,0 +1,250 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\ResourceLocator;
|
||||
|
||||
use FilesystemIterator;
|
||||
|
||||
/**
|
||||
* Implements FilesystemIterator for uniform resource locator.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\ResourceLocator
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class UniformResourceIterator extends FilesystemIterator
|
||||
{
|
||||
/**
|
||||
* @var FilesystemIterator
|
||||
*/
|
||||
protected $iterator;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $found;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $stack;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $flags;
|
||||
|
||||
/**
|
||||
* @var UniformResourceLocator
|
||||
*/
|
||||
protected $locator;
|
||||
|
||||
public function __construct($path, $flags = null, UniformResourceLocator $locator = null)
|
||||
{
|
||||
if (!$locator) {
|
||||
throw new \BadMethodCallException('Use $locator->getIterator() instead');
|
||||
}
|
||||
|
||||
$this->path = $path;
|
||||
$this->setFlags($flags);
|
||||
$this->locator = $locator;
|
||||
$this->rewind();
|
||||
}
|
||||
|
||||
public function current()
|
||||
{
|
||||
if ($this->flags & static::CURRENT_AS_SELF) {
|
||||
return $this;
|
||||
}
|
||||
return $this->iterator->current();
|
||||
}
|
||||
|
||||
public function key()
|
||||
{
|
||||
return $this->iterator->key();
|
||||
}
|
||||
|
||||
public function next()
|
||||
{
|
||||
do {
|
||||
$found = $this->findNext();
|
||||
} while ($found && !empty($this->found[$found]));
|
||||
|
||||
if ($found) {
|
||||
// Mark the file as found.
|
||||
$this->found[$found] = true;
|
||||
}
|
||||
}
|
||||
|
||||
public function valid()
|
||||
{
|
||||
return $this->iterator && $this->iterator->valid();
|
||||
}
|
||||
|
||||
public function rewind()
|
||||
{
|
||||
$this->found = [];
|
||||
$this->stack = $this->locator->findResources($this->path);
|
||||
$this->next();
|
||||
}
|
||||
|
||||
public function getUrl()
|
||||
{
|
||||
$path = $this->path . (substr($this->path, -1, 1) === '/' ? '' : '/');
|
||||
return $path . $this->iterator->getFilename();
|
||||
}
|
||||
|
||||
public function seek($position)
|
||||
{
|
||||
throw new \RuntimeException('Seek not implemented');
|
||||
}
|
||||
|
||||
public function getATime()
|
||||
{
|
||||
return $this->iterator->getATime();
|
||||
}
|
||||
|
||||
public function getBasename($suffix = null)
|
||||
{
|
||||
return $this->iterator->getBasename($suffix);
|
||||
}
|
||||
|
||||
public function getCTime()
|
||||
{
|
||||
return $this->iterator->getCTime();
|
||||
}
|
||||
|
||||
public function getExtension()
|
||||
{
|
||||
return $this->iterator->getExtension();
|
||||
}
|
||||
|
||||
public function getFilename()
|
||||
{
|
||||
return $this->iterator->getFilename();
|
||||
}
|
||||
|
||||
public function getGroup()
|
||||
{
|
||||
return $this->iterator->getGroup();
|
||||
}
|
||||
|
||||
public function getInode()
|
||||
{
|
||||
return $this->iterator->getInode();
|
||||
}
|
||||
|
||||
public function getMTime()
|
||||
{
|
||||
return $this->iterator->getMTime();
|
||||
}
|
||||
|
||||
public function getOwner()
|
||||
{
|
||||
return $this->iterator->getOwner();
|
||||
}
|
||||
|
||||
public function getPath()
|
||||
{
|
||||
return $this->iterator->getPath();
|
||||
}
|
||||
|
||||
public function getPathname()
|
||||
{
|
||||
return $this->iterator->getPathname();
|
||||
}
|
||||
|
||||
public function getPerms()
|
||||
{
|
||||
return $this->iterator->getPerms();
|
||||
}
|
||||
|
||||
public function getSize()
|
||||
{
|
||||
return $this->iterator->getSize();
|
||||
}
|
||||
|
||||
public function getType()
|
||||
{
|
||||
return $this->iterator->getType();
|
||||
}
|
||||
|
||||
public function isDir()
|
||||
{
|
||||
return $this->iterator->isDir();
|
||||
}
|
||||
|
||||
public function isDot()
|
||||
{
|
||||
return $this->iterator->isDot();
|
||||
}
|
||||
|
||||
public function isExecutable()
|
||||
{
|
||||
return $this->iterator->isExecutable();
|
||||
}
|
||||
|
||||
public function isFile()
|
||||
{
|
||||
return $this->iterator->isFile();
|
||||
}
|
||||
|
||||
public function isLink()
|
||||
{
|
||||
return $this->iterator->isLink();
|
||||
}
|
||||
|
||||
public function isReadable()
|
||||
{
|
||||
return $this->iterator->isReadable();
|
||||
}
|
||||
|
||||
public function isWritable()
|
||||
{
|
||||
return $this->iterator->isWritable();
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->iterator->__toString();
|
||||
}
|
||||
|
||||
public function getFlags()
|
||||
{
|
||||
return $this->flags;
|
||||
}
|
||||
|
||||
public function setFlags($flags = null)
|
||||
{
|
||||
$this->flags = $flags === null ? static::KEY_AS_PATHNAME | static::CURRENT_AS_SELF | static::SKIP_DOTS : $flags;
|
||||
|
||||
if ($this->iterator) {
|
||||
$this->iterator->setFlags($this->flags);
|
||||
}
|
||||
}
|
||||
|
||||
protected function findNext()
|
||||
{
|
||||
if ($this->iterator) {
|
||||
$this->iterator->next();
|
||||
}
|
||||
|
||||
if (!$this->valid()) {
|
||||
do {
|
||||
// Move to the next iterator if it exists.
|
||||
$path = array_shift($this->stack);
|
||||
|
||||
if (!isset($path)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->iterator = new \FilesystemIterator($path, $this->getFlags());
|
||||
} while (!$this->iterator->valid());
|
||||
}
|
||||
|
||||
return $this->getFilename();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,338 @@
|
||||
<?php
|
||||
|
||||
namespace RocketTheme\Toolbox\ResourceLocator;
|
||||
|
||||
/**
|
||||
* Implements Uniform Resource Location.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\ResourceLocator
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*
|
||||
* @link http://webmozarts.com/2013/06/19/the-power-of-uniform-resource-location-in-php/
|
||||
*/
|
||||
class UniformResourceLocator implements ResourceLocatorInterface
|
||||
{
|
||||
/**
|
||||
* @var string Base URL for all the streams.
|
||||
*/
|
||||
public $base;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $schemes = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $cache = [];
|
||||
|
||||
public function __construct($base = null)
|
||||
{
|
||||
// Normalize base path.
|
||||
$this->base = rtrim(str_replace('\\', '/', $base ?: getcwd()), '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return iterator for the resource URI.
|
||||
*
|
||||
* @param string $uri
|
||||
* @param int $flags See constants from FilesystemIterator class.
|
||||
* @return UniformResourceIterator
|
||||
*/
|
||||
public function getIterator($uri, $flags = null)
|
||||
{
|
||||
return new UniformResourceIterator($uri, $flags, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return recursive iterator for the resource URI.
|
||||
*
|
||||
* @param string $uri
|
||||
* @param int $flags See constants from FilesystemIterator class.
|
||||
* @return RecursiveUniformResourceIterator
|
||||
*/
|
||||
public function getRecursiveIterator($uri, $flags = null)
|
||||
{
|
||||
return new RecursiveUniformResourceIterator($uri, $flags, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset locator by removing all the schemes.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->schemes = [];
|
||||
$this->cache = [];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new paths to the scheme.
|
||||
*
|
||||
* @param string $scheme
|
||||
* @param string $prefix
|
||||
* @param string|array $paths
|
||||
* @param bool $override Add path as override.
|
||||
* @param bool $force True to add paths even if them do not exist.
|
||||
* @throws \BadMethodCallException
|
||||
*/
|
||||
public function addPath($scheme, $prefix, $paths, $override = false, $force = false)
|
||||
{
|
||||
$list = [];
|
||||
foreach((array) $paths as $path) {
|
||||
if (is_array($path)) {
|
||||
// Support stream lookup in ['theme', 'path/to'] format.
|
||||
if (count($path) != 2) {
|
||||
throw new \BadMethodCallException('Invalid stream path given.');
|
||||
}
|
||||
$list[] = $path;
|
||||
} elseif (strstr($path, '://')) {
|
||||
// Support stream lookup in 'theme://path/to' format.
|
||||
$list[] = explode('://', $path, 2);
|
||||
} else {
|
||||
// Normalize path.
|
||||
$path = rtrim(str_replace('\\', '/', $path), '/');
|
||||
if ($force || @file_exists("{$this->base}/{$path}") || @file_exists($path)) {
|
||||
// Support for absolute and relative paths.
|
||||
$list[] = $path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->schemes[$scheme][$prefix])) {
|
||||
$list = $override
|
||||
? array_merge($this->schemes[$scheme][$prefix], $list)
|
||||
: array_merge($list, $this->schemes[$scheme][$prefix]);
|
||||
}
|
||||
|
||||
$this->schemes[$scheme][$prefix] = $list;
|
||||
|
||||
// Sort in reverse order to get longer prefixes to be matched first.
|
||||
krsort($this->schemes[$scheme]);
|
||||
|
||||
$this->cache = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return base directory.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBase()
|
||||
{
|
||||
return $this->base;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return true if scheme has been defined.
|
||||
*
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public function schemeExists($name)
|
||||
{
|
||||
return isset($this->schemes[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return defined schemes.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getSchemes()
|
||||
{
|
||||
return array_keys($this->schemes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all scheme lookup paths.
|
||||
*
|
||||
* @param $scheme
|
||||
* @return array
|
||||
*/
|
||||
public function getPaths($scheme)
|
||||
{
|
||||
return isset($this->schemes[$scheme]) ? $this->schemes[$scheme] : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $uri
|
||||
* @return string|bool
|
||||
* @throws \BadMethodCallException
|
||||
*/
|
||||
public function __invoke($uri)
|
||||
{
|
||||
if (!is_string($uri)) {
|
||||
throw new \BadMethodCallException('Invalid parameter $uri.');
|
||||
}
|
||||
return $this->findCached($uri, false, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find highest priority instance from a resource.
|
||||
*
|
||||
* @param string $uri Input URI to be searched.
|
||||
* @param bool $absolute Whether to return absolute path.
|
||||
* @param bool $first Whether to return first path even if it doesn't exist.
|
||||
* @throws \BadMethodCallException
|
||||
* @return string|bool
|
||||
*/
|
||||
public function findResource($uri, $absolute = true, $first = false)
|
||||
{
|
||||
if (!is_string($uri)) {
|
||||
throw new \BadMethodCallException('Invalid parameter $uri.');
|
||||
}
|
||||
return $this->findCached($uri, false, $absolute, $first);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all instances from a resource.
|
||||
*
|
||||
* @param string $uri Input URI to be searched.
|
||||
* @param bool $absolute Whether to return absolute path.
|
||||
* @param bool $all Whether to return all paths even if they don't exist.
|
||||
* @throws \BadMethodCallException
|
||||
* @return array
|
||||
*/
|
||||
public function findResources($uri, $absolute = true, $all = false)
|
||||
{
|
||||
if (!is_string($uri)) {
|
||||
throw new \BadMethodCallException('Invalid parameter $uri.');
|
||||
}
|
||||
|
||||
return $this->findCached($uri, true, $absolute, $all);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all instances from a list of resources.
|
||||
*
|
||||
* @param array $uris Input URIs to be searched.
|
||||
* @param bool $absolute Whether to return absolute path.
|
||||
* @param bool $all Whether to return all paths even if they don't exist.
|
||||
* @throws \BadMethodCallException
|
||||
* @return array
|
||||
*/
|
||||
public function mergeResources(array $uris, $absolute = true, $all = false)
|
||||
{
|
||||
$uris = array_unique($uris);
|
||||
|
||||
$list = [];
|
||||
foreach ($uris as $uri) {
|
||||
$list = array_merge($list, $this->findResources($uri, $absolute, $all));
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse resource.
|
||||
*
|
||||
* @param $uri
|
||||
* @return array
|
||||
* @throws \InvalidArgumentException
|
||||
* @internal
|
||||
*/
|
||||
protected function parseResource($uri)
|
||||
{
|
||||
$segments = explode('://', $uri, 2);
|
||||
$file = array_pop($segments);
|
||||
$scheme = array_pop($segments);
|
||||
|
||||
if (!$scheme) {
|
||||
$scheme = 'file';
|
||||
}
|
||||
|
||||
if (!$file && $scheme == 'file') {
|
||||
$file = $this->base;
|
||||
}
|
||||
|
||||
return [$scheme, $file];
|
||||
}
|
||||
|
||||
|
||||
protected function findCached($uri, $array, $absolute, $all)
|
||||
{
|
||||
// Local caching: make sure that the function gets only called at once for each file.
|
||||
$key = $uri .'@'. (int) $array . (int) $absolute . (int) $all;
|
||||
|
||||
if (!isset($this->cache[$key])) {
|
||||
list ($scheme, $file) = $this->parseResource($uri);
|
||||
|
||||
$this->cache[$key] = $this->find($scheme, $file, $array, $absolute, $all);
|
||||
}
|
||||
|
||||
return $this->cache[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $scheme
|
||||
* @param string $file
|
||||
* @param bool $array
|
||||
* @param bool $absolute
|
||||
* @param bool $all
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* @return array|string|bool
|
||||
* @internal
|
||||
*/
|
||||
protected function find($scheme, $file, $array, $absolute, $all)
|
||||
{
|
||||
if (!isset($this->schemes[$scheme])) {
|
||||
throw new \InvalidArgumentException("Invalid resource {$scheme}://");
|
||||
}
|
||||
|
||||
$results = $array ? [] : false;
|
||||
foreach ($this->schemes[$scheme] as $prefix => $paths) {
|
||||
if ($prefix && strpos($file, $prefix) !== 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove prefix from filename.
|
||||
$filename = '/' . trim(substr($file, strlen($prefix)), '\/');
|
||||
|
||||
foreach ($paths as $path) {
|
||||
if (is_array($path)) {
|
||||
// Handle scheme lookup.
|
||||
$relPath = trim(trim($path[1], '/') . $filename, '/');
|
||||
$found = $this->find($path[0], $relPath, $array, $absolute, $all);
|
||||
if ($found) {
|
||||
if (!$array) {
|
||||
return $found;
|
||||
}
|
||||
$results = array_merge($results, $found);
|
||||
}
|
||||
} else {
|
||||
// TODO: We could provide some extra information about the path to remove preg_match().
|
||||
// Check absolute paths for both unix and windows
|
||||
if (!$path || !preg_match('`^/|\w+:`', $path)) {
|
||||
// Handle relative path lookup.
|
||||
$relPath = trim($path . $filename, '/');
|
||||
$fullPath = $this->base . '/' . $relPath;
|
||||
} else {
|
||||
// Handle absolute path lookup.
|
||||
$fullPath = rtrim($path . $filename, '/');
|
||||
if (!$absolute) {
|
||||
throw new \RuntimeException('UniformResourceLocator: Absolute stream path with relative lookup not allowed', 500);
|
||||
}
|
||||
}
|
||||
|
||||
if ($all || file_exists($fullPath)) {
|
||||
$current = $absolute ? $fullPath : $relPath;
|
||||
if (!$array) {
|
||||
return $current;
|
||||
}
|
||||
$results[] = $current;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\Session;
|
||||
|
||||
/**
|
||||
* Implements session messages.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\Session
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Message
|
||||
{
|
||||
/**
|
||||
* @var array|string[]
|
||||
*/
|
||||
protected $messages = array();
|
||||
|
||||
/**
|
||||
* Add message to the queue.
|
||||
*
|
||||
* @param string $message
|
||||
* @param string $scope
|
||||
* @return $this
|
||||
*/
|
||||
public function add($message, $scope = 'default')
|
||||
{
|
||||
$key = md5($scope.'~'.$message);
|
||||
$message = array('message' => $message, 'scope' => $scope);
|
||||
|
||||
// don't add duplicates
|
||||
if (!array_key_exists($key, $this->messages)) {
|
||||
$this->messages[$key] = $message;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear message queue.
|
||||
*
|
||||
* @param string $scope
|
||||
* @return $this
|
||||
*/
|
||||
public function clear($scope = null)
|
||||
{
|
||||
if ($scope === null) {
|
||||
$this->messages = array();
|
||||
} else {
|
||||
foreach ($this->messages as $key => $message) {
|
||||
if ($message['scope'] == $scope) {
|
||||
unset($this->messages[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all messages.
|
||||
*
|
||||
* @param string $scope
|
||||
* @return array
|
||||
*/
|
||||
public function all($scope = null)
|
||||
{
|
||||
if ($scope === null) {
|
||||
return array_values($this->messages);
|
||||
}
|
||||
|
||||
$messages = array();
|
||||
foreach ($this->messages as $message) {
|
||||
if ($message['scope'] == $scope) {
|
||||
$messages[] = $message;
|
||||
}
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch and clear message queue.
|
||||
*
|
||||
* @param string $scope
|
||||
* @return array
|
||||
*/
|
||||
public function fetch($scope = null)
|
||||
{
|
||||
$messages = $this->all($scope);
|
||||
$this->clear($scope);
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
}
|
||||
+257
@@ -0,0 +1,257 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\Session;
|
||||
|
||||
/**
|
||||
* Implements Session handling.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\Session
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Session implements \IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $started = false;
|
||||
|
||||
/**
|
||||
* @var Session
|
||||
*/
|
||||
static $instance;
|
||||
|
||||
/**
|
||||
* @param int $lifetime Defaults to 1800 seconds.
|
||||
* @param string $path Cookie path.
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function __construct($lifetime, $path)
|
||||
{
|
||||
// Session is a singleton.
|
||||
if (isset(self::$instance)) {
|
||||
throw new \RuntimeException("Session has already been initialized.", 500);
|
||||
}
|
||||
|
||||
// Destroy any existing sessions started with session.auto_start
|
||||
if (session_id())
|
||||
{
|
||||
session_unset();
|
||||
session_destroy();
|
||||
}
|
||||
|
||||
// Disable transparent sid support
|
||||
ini_set('session.use_trans_sid', 0);
|
||||
|
||||
// Only allow cookies
|
||||
ini_set('session.use_cookies', 1);
|
||||
|
||||
session_name('msF9kJcW');
|
||||
session_set_cookie_params($lifetime, $path);
|
||||
register_shutdown_function([$this, 'close']);
|
||||
session_cache_limiter('nocache');
|
||||
|
||||
if (isset($this->count)) {
|
||||
$this->count++;
|
||||
} else {
|
||||
$this->count = 1;
|
||||
}
|
||||
|
||||
self::$instance = $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current session instance.
|
||||
*
|
||||
* @return Session
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function instance()
|
||||
{
|
||||
if (!isset(self::$instance)) {
|
||||
throw new \RuntimeException("Session hasn't been initialized.", 500);
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the session storage
|
||||
*
|
||||
* @return $this
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function start()
|
||||
{
|
||||
if (!session_start()) {
|
||||
throw new \RuntimeException('Failed to start session.', 500);
|
||||
}
|
||||
|
||||
$this->started = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get session ID
|
||||
*
|
||||
* @return string Session ID
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return session_id();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set session Id
|
||||
*
|
||||
* @param string $id Session ID
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setId($id)
|
||||
{
|
||||
session_id($id);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get session name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return session_name();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set session name
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
session_name($name);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates the current session.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function invalidate()
|
||||
{
|
||||
$params = session_get_cookie_params();
|
||||
setcookie(session_name(), '', time() - 42000,
|
||||
$params['path'], $params['domain'],
|
||||
$params['secure'], $params['httponly']
|
||||
);
|
||||
|
||||
session_unset();
|
||||
session_destroy();
|
||||
|
||||
$this->started = false;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force the session to be saved and closed
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
if ($this->started) {
|
||||
session_write_close();
|
||||
}
|
||||
|
||||
$this->started = false;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an attribute is defined.
|
||||
*
|
||||
* @param string $name The attribute name
|
||||
*
|
||||
* @return bool True if the attribute is defined, false otherwise
|
||||
*/
|
||||
public function __isset($name)
|
||||
{
|
||||
return isset($_SESSION[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an attribute.
|
||||
*
|
||||
* @param string $name The attribute name
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
return isset($_SESSION[$name]) ? $_SESSION[$name] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an attribute.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
{
|
||||
$_SESSION[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an attribute.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return mixed The removed value or null when it does not exist
|
||||
*/
|
||||
public function __unset($name)
|
||||
{
|
||||
unset($_SESSION[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns attributes.
|
||||
*
|
||||
* @return array Attributes
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
return $_SESSION;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve an external iterator
|
||||
*
|
||||
* @return \ArrayIterator Return an ArrayIterator of $_SESSION
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($_SESSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the session was started.
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function started()
|
||||
{
|
||||
return $this->started;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
use RocketTheme\Toolbox\Session;
|
||||
|
||||
class SessionMessageTest extends PHPUnit_Framework_TestCase {
|
||||
|
||||
public function testDummy()
|
||||
{
|
||||
$message = new Message;
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\StreamWrapper;
|
||||
|
||||
use RocketTheme\Toolbox\ResourceLocator\ResourceLocatorInterface;
|
||||
|
||||
/**
|
||||
* Implements Read Only Streams.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\StreamWrapper
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class ReadOnlyStream extends Stream implements StreamInterface
|
||||
{
|
||||
/**
|
||||
* @var ResourceLocatorInterface
|
||||
*/
|
||||
protected static $locator;
|
||||
|
||||
public function stream_open($uri, $mode, $options, &$opened_url)
|
||||
{
|
||||
if (!in_array($mode, ['r', 'rb', 'rt'])) {
|
||||
if ($options & STREAM_REPORT_ERRORS) {
|
||||
trigger_error('stream_open() write modes not supported for read-only stream wrappers', E_USER_WARNING);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
$path = $this->getPath($uri);
|
||||
|
||||
if (!$path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->handle = ($options & STREAM_REPORT_ERRORS) ? fopen($path, $mode) : @fopen($path, $mode);
|
||||
|
||||
return (bool) $this->handle;
|
||||
}
|
||||
|
||||
public function stream_lock($operation)
|
||||
{
|
||||
// Disallow exclusive lock or non-blocking lock requests
|
||||
if (!in_array($operation, [LOCK_SH, LOCK_UN, LOCK_SH | LOCK_NB])) {
|
||||
trigger_error(
|
||||
'stream_lock() exclusive lock operations not supported for read-only stream wrappers',
|
||||
E_USER_WARNING
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
return flock($this->handle, $operation);
|
||||
}
|
||||
|
||||
public function stream_write($data)
|
||||
{
|
||||
throw new \BadMethodCallException('stream_write() not supported for read-only stream wrappers');
|
||||
}
|
||||
|
||||
public function unlink($uri)
|
||||
{
|
||||
throw new \BadMethodCallException('unlink() not supported for read-only stream wrappers');
|
||||
}
|
||||
|
||||
public function rename($from_uri, $to_uri)
|
||||
{
|
||||
throw new \BadMethodCallException('rename() not supported for read-only stream wrappers');
|
||||
}
|
||||
|
||||
public function mkdir($uri, $mode, $options)
|
||||
{
|
||||
throw new \BadMethodCallException('mkdir() not supported for read-only stream wrappers');
|
||||
}
|
||||
|
||||
public function rmdir($uri, $options)
|
||||
{
|
||||
throw new \BadMethodCallException('rmdir() not supported for read-only stream wrappers');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\StreamWrapper;
|
||||
|
||||
use RocketTheme\Toolbox\ResourceLocator\ResourceLocatorInterface;
|
||||
|
||||
/**
|
||||
* Implements Read/Write Streams.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\StreamWrapper
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Stream implements StreamInterface
|
||||
{
|
||||
/**
|
||||
* A generic resource handle.
|
||||
*
|
||||
* @var Resource
|
||||
*/
|
||||
protected $handle = null;
|
||||
|
||||
/**
|
||||
* @var ResourceLocatorInterface
|
||||
*/
|
||||
protected static $locator;
|
||||
|
||||
/**
|
||||
* @param ResourceLocatorInterface $locator
|
||||
*/
|
||||
public static function setLocator(ResourceLocatorInterface $locator)
|
||||
{
|
||||
static::$locator = $locator;
|
||||
}
|
||||
|
||||
public function stream_open($uri, $mode, $options, &$opened_url)
|
||||
{
|
||||
$path = $this->getPath($uri, $mode);
|
||||
|
||||
if (!$path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->handle = ($options & STREAM_REPORT_ERRORS) ? fopen($path, $mode) : @fopen($path, $mode);
|
||||
|
||||
return (bool) $this->handle;
|
||||
}
|
||||
|
||||
public function stream_close()
|
||||
{
|
||||
return fclose($this->handle);
|
||||
}
|
||||
|
||||
public function stream_lock($operation)
|
||||
{
|
||||
if (in_array($operation, [LOCK_SH, LOCK_EX, LOCK_UN, LOCK_NB])) {
|
||||
return flock($this->handle, $operation);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function stream_metadata($uri, $option, $value)
|
||||
{
|
||||
switch ($option) {
|
||||
case STREAM_META_TOUCH:
|
||||
list ($time, $atime) = $value;
|
||||
return touch($uri, $time, $atime);
|
||||
|
||||
case STREAM_META_OWNER_NAME:
|
||||
case STREAM_META_OWNER:
|
||||
return chown($uri, $value);
|
||||
|
||||
case STREAM_META_GROUP_NAME:
|
||||
case STREAM_META_GROUP:
|
||||
return chgrp($uri, $value);
|
||||
|
||||
case STREAM_META_ACCESS:
|
||||
return chmod($uri, $value);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function stream_read($count)
|
||||
{
|
||||
return fread($this->handle, $count);
|
||||
}
|
||||
|
||||
public function stream_write($data)
|
||||
{
|
||||
return fwrite($this->handle, $data);
|
||||
}
|
||||
|
||||
public function stream_eof()
|
||||
{
|
||||
return feof($this->handle);
|
||||
}
|
||||
|
||||
public function stream_seek($offset, $whence)
|
||||
{
|
||||
// fseek returns 0 on success and -1 on a failure.
|
||||
return !fseek($this->handle, $offset, $whence);
|
||||
}
|
||||
|
||||
public function stream_flush()
|
||||
{
|
||||
return fflush($this->handle);
|
||||
}
|
||||
|
||||
public function stream_tell()
|
||||
{
|
||||
return ftell($this->handle);
|
||||
}
|
||||
|
||||
public function stream_stat()
|
||||
{
|
||||
return fstat($this->handle);
|
||||
}
|
||||
|
||||
public function unlink($uri)
|
||||
{
|
||||
$path = $this->getPath($uri);
|
||||
|
||||
if (!$path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return unlink($path);
|
||||
}
|
||||
|
||||
public function rename($fromUri, $toUri)
|
||||
{
|
||||
$fromPath = $this->getPath($fromUri);
|
||||
$toPath = $this->getPath($toUri);
|
||||
|
||||
if (!($fromPath && $toPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return rename($fromPath, $toPath);
|
||||
}
|
||||
|
||||
public function mkdir($uri, $mode, $options)
|
||||
{
|
||||
$recursive = (bool) ($options & STREAM_MKDIR_RECURSIVE);
|
||||
$path = $this->getPath($uri, $recursive ? $mode : null);
|
||||
|
||||
if (!$path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ($options & STREAM_REPORT_ERRORS) ? mkdir($path, $mode, $recursive) : @mkdir($path, $mode, $recursive);
|
||||
}
|
||||
|
||||
public function rmdir($uri, $options)
|
||||
{
|
||||
$path = $this->getPath($uri);
|
||||
|
||||
if (!$path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ($options & STREAM_REPORT_ERRORS) ? rmdir($path) : @rmdir($path);
|
||||
}
|
||||
|
||||
public function url_stat($uri, $flags)
|
||||
{
|
||||
$path = $this->getPath($uri);
|
||||
|
||||
if (!$path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Suppress warnings if requested or if the file or directory does not
|
||||
// exist. This is consistent with PHP's plain filesystem stream wrapper.
|
||||
return ($flags & STREAM_URL_STAT_QUIET || !file_exists($path)) ? @stat($path) : stat($path);
|
||||
}
|
||||
|
||||
public function dir_opendir($uri, $options)
|
||||
{
|
||||
$path = $this->getPath($uri);
|
||||
|
||||
if (!$path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->handle = opendir($path);
|
||||
|
||||
return (bool) $this->handle;
|
||||
}
|
||||
|
||||
public function dir_readdir()
|
||||
{
|
||||
return readdir($this->handle);
|
||||
}
|
||||
|
||||
public function dir_rewinddir()
|
||||
{
|
||||
rewinddir($this->handle);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function dir_closedir()
|
||||
{
|
||||
closedir($this->handle);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function getPath($uri, $mode = null)
|
||||
{
|
||||
$path = $this->findPath($uri);
|
||||
|
||||
if ($mode == null || !$path || file_exists($path)) {
|
||||
return $path;
|
||||
}
|
||||
|
||||
if ($mode[0] == 'r') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We are either opening a file or creating directory.
|
||||
list($scheme, $target) = explode('://', $uri, 2);
|
||||
|
||||
$path = $this->findPath($scheme . '://' . dirname($target));
|
||||
|
||||
if (!$path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $path . '/' . basename($uri);
|
||||
}
|
||||
|
||||
protected function findPath($uri)
|
||||
{
|
||||
return static::$locator ? static::$locator->findResource($uri) : false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\StreamWrapper;
|
||||
|
||||
/**
|
||||
* Class StreamBuilder
|
||||
* @package RocketTheme\Toolbox\StreamWrapper
|
||||
*/
|
||||
class StreamBuilder
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $items = [];
|
||||
|
||||
public function __construct(array $items = [])
|
||||
{
|
||||
foreach ($items as $scheme => $handler) {
|
||||
$this->add($scheme, $handler);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $scheme
|
||||
* @param $handler
|
||||
* @return $this
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function add($scheme, $handler)
|
||||
{
|
||||
if (isset($this->items[$scheme])) {
|
||||
if ($handler == $this->items[$scheme]) {
|
||||
return $this;
|
||||
}
|
||||
throw new \InvalidArgumentException("Stream '{$scheme}' has already been initialized.");
|
||||
}
|
||||
|
||||
if (!is_subclass_of($handler, 'RocketTheme\Toolbox\StreamWrapper\StreamInterface')) {
|
||||
throw new \InvalidArgumentException("Stream '{$scheme}' has unknown or invalid type.");
|
||||
}
|
||||
|
||||
if (!@stream_wrapper_register($scheme, $handler)) {
|
||||
throw new \InvalidArgumentException("Stream '{$scheme}' could not be initialized.");
|
||||
}
|
||||
|
||||
$this->items[$scheme] = $handler;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $scheme
|
||||
* @return $this
|
||||
*/
|
||||
public function remove($scheme)
|
||||
{
|
||||
if (isset($this->items[$scheme])) {
|
||||
stream_wrapper_unregister($scheme);
|
||||
unset($this->items[$scheme]);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getStreams()
|
||||
{
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $scheme
|
||||
* @return bool
|
||||
*/
|
||||
public function isStream($scheme)
|
||||
{
|
||||
return isset($this->items[$scheme]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $scheme
|
||||
* @return null
|
||||
*/
|
||||
public function getStreamType($scheme)
|
||||
{
|
||||
return isset($this->items[$scheme]) ? $this->items[$scheme] : null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
<?php
|
||||
namespace RocketTheme\Toolbox\StreamWrapper;
|
||||
|
||||
/**
|
||||
* Defines Generic PHP stream wrapper interface.
|
||||
*
|
||||
* @package RocketTheme\Toolbox\StreamWrapper
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*
|
||||
* @see http://www.php.net/manual/class.streamwrapper.php
|
||||
*/
|
||||
interface StreamInterface
|
||||
{
|
||||
/**
|
||||
* Support for fopen(), file_get_contents(), file_put_contents() etc.
|
||||
*
|
||||
* @param string $uri A string containing the URI to the file to open.
|
||||
* @param string $mode The file mode ("r", "wb" etc.).
|
||||
* @param int $options A bit mask of STREAM_USE_PATH and STREAM_REPORT_ERRORS.
|
||||
* @param string $opened_url A string containing the path actually opened.
|
||||
*
|
||||
* @return bool Returns TRUE if file was opened successfully.
|
||||
* @see http://php.net/manual/streamwrapper.stream-open.php
|
||||
*/
|
||||
public function stream_open($uri, $mode, $options, &$opened_url);
|
||||
|
||||
/**
|
||||
* Support for fclose().
|
||||
*
|
||||
* @return bool TRUE if stream was successfully closed.
|
||||
* @see http://php.net/manual/streamwrapper.stream-close.php
|
||||
*/
|
||||
public function stream_close();
|
||||
|
||||
/**
|
||||
* Support for flock().
|
||||
*
|
||||
* @param $operation
|
||||
* One of the following:
|
||||
* - LOCK_SH to acquire a shared lock (reader).
|
||||
* - LOCK_EX to acquire an exclusive lock (writer).
|
||||
* - LOCK_UN to release a lock (shared or exclusive).
|
||||
* - LOCK_NB if you don't want flock() to block while locking (not
|
||||
* supported on Windows).
|
||||
*
|
||||
* @return bool Always returns TRUE at the present time.
|
||||
* @see http://php.net/manual/streamwrapper.stream-lock.php
|
||||
*/
|
||||
public function stream_lock($operation);
|
||||
|
||||
/**
|
||||
* Support for touch(), chmod(), chown(), chgrp().
|
||||
*
|
||||
* @param $path
|
||||
* The file path or URL to set metadata. Note that in the case of a URL, it must be a :// delimited URL.
|
||||
* Other URL forms are not supported.
|
||||
*
|
||||
* @param $option
|
||||
* One of:
|
||||
* - STREAM_META_TOUCH The method was called in response to touch()
|
||||
* - STREAM_META_OWNER_NAME The method was called in response to chown() with string parameter
|
||||
* - STREAM_META_OWNER The method was called in response to chown()
|
||||
* - STREAM_META_GROUP_NAME The method was called in response to chgrp()
|
||||
* - STREAM_META_GROUP The method was called in response to chgrp()
|
||||
* - STREAM_META_ACCESS The method was called in response to chmod()
|
||||
*
|
||||
* @param $value
|
||||
* If option is
|
||||
* - STREAM_META_TOUCH: Array consisting of two arguments of the touch() function.
|
||||
* - STREAM_META_OWNER_NAME or
|
||||
* STREAM_META_GROUP_NAME: The name of the owner user/group as string.
|
||||
* - STREAM_META_OWNER or
|
||||
* STREAM_META_GROUP: The value owner user/group argument as integer.
|
||||
* - STREAM_META_ACCESS: The argument of the chmod() as integer.
|
||||
|
||||
|
||||
*
|
||||
* @return bool
|
||||
* @see http://php.net/manual/en/streamwrapper.stream-metadata.php
|
||||
*/
|
||||
public function stream_metadata($path, $option, $value);
|
||||
|
||||
/**
|
||||
* Support for fread(), file_get_contents() etc.
|
||||
*
|
||||
* @param $count
|
||||
* Maximum number of bytes to be read.
|
||||
*
|
||||
* @return string|bool The string that was read, or FALSE in case of an error.
|
||||
* @see http://php.net/manual/streamwrapper.stream-read.php
|
||||
*/
|
||||
public function stream_read($count);
|
||||
|
||||
/**
|
||||
* Support for fwrite(), file_put_contents() etc.
|
||||
*
|
||||
* @param $data
|
||||
* The string to be written.
|
||||
*
|
||||
* @return int The number of bytes written (integer).
|
||||
* @see http://php.net/manual/streamwrapper.stream-write.php
|
||||
*/
|
||||
public function stream_write($data);
|
||||
|
||||
/**
|
||||
* Support for feof().
|
||||
*
|
||||
* @return bool TRUE if end-of-file has been reached.
|
||||
* @see http://php.net/manual/streamwrapper.stream-eof.php
|
||||
*/
|
||||
public function stream_eof();
|
||||
|
||||
/**
|
||||
* Support for fseek().
|
||||
*
|
||||
* @param $offset
|
||||
* The byte offset to got to.
|
||||
* @param $whence
|
||||
* SEEK_SET, SEEK_CUR, or SEEK_END.
|
||||
*
|
||||
* @return bool TRUE on success.
|
||||
* @see http://php.net/manual/streamwrapper.stream-seek.php
|
||||
*/
|
||||
public function stream_seek($offset, $whence);
|
||||
|
||||
/**
|
||||
* Support for fflush().
|
||||
*
|
||||
* @return bool TRUE if data was successfully stored (or there was no data to store).
|
||||
* @see http://php.net/manual/streamwrapper.stream-flush.php
|
||||
*/
|
||||
public function stream_flush();
|
||||
|
||||
/**
|
||||
* Support for ftell().
|
||||
*
|
||||
* @return int The current offset in bytes from the beginning of file.
|
||||
* @see http://php.net/manual/streamwrapper.stream-tell.php
|
||||
*/
|
||||
public function stream_tell();
|
||||
|
||||
/**
|
||||
* Support for fstat().
|
||||
*
|
||||
* @return array An array with file status, or FALSE in case of an error - see fstat()
|
||||
* @see http://php.net/manual/streamwrapper.stream-stat.php
|
||||
*/
|
||||
public function stream_stat();
|
||||
|
||||
/**
|
||||
* Support for unlink().
|
||||
*
|
||||
* @param $uri
|
||||
* A string containing the URI to the resource to delete.
|
||||
*
|
||||
* @return
|
||||
* TRUE if resource was successfully deleted.
|
||||
* @see http://php.net/manual/streamwrapper.unlink.php
|
||||
*/
|
||||
public function unlink($uri);
|
||||
|
||||
/**
|
||||
* Support for rename().
|
||||
*
|
||||
* @param $from_uri ,
|
||||
* The URI to the file to rename.
|
||||
* @param $to_uri
|
||||
* The new URI for file.
|
||||
*
|
||||
* @return bool TRUE if file was successfully renamed.
|
||||
* @see http://php.net/manual/streamwrapper.rename.php
|
||||
*/
|
||||
public function rename($from_uri, $to_uri);
|
||||
|
||||
/**
|
||||
* Support for mkdir().
|
||||
*
|
||||
* @param $uri
|
||||
* A string containing the URI to the directory to create.
|
||||
* @param $mode
|
||||
* Permission flags - see mkdir().
|
||||
* @param $options
|
||||
* A bit mask of STREAM_REPORT_ERRORS and STREAM_MKDIR_RECURSIVE.
|
||||
*
|
||||
* @return bool TRUE if directory was successfully created.
|
||||
* @see http://php.net/manual/streamwrapper.mkdir.php
|
||||
*/
|
||||
public function mkdir($uri, $mode, $options);
|
||||
|
||||
/**
|
||||
* Support for rmdir().
|
||||
*
|
||||
* @param $uri
|
||||
* A string containing the URI to the directory to delete.
|
||||
* @param $options
|
||||
* A bit mask of STREAM_REPORT_ERRORS.
|
||||
*
|
||||
* @return
|
||||
* TRUE if directory was successfully removed.
|
||||
*
|
||||
* @see http://php.net/manual/streamwrapper.rmdir.php
|
||||
*/
|
||||
public function rmdir($uri, $options);
|
||||
|
||||
/**
|
||||
* Support for stat().
|
||||
*
|
||||
* @param $uri
|
||||
* A string containing the URI to get information about.
|
||||
* @param $flags
|
||||
* A bit mask of STREAM_URL_STAT_LINK and STREAM_URL_STAT_QUIET.
|
||||
*
|
||||
* @return array An array with file status, or FALSE in case of an error - see fstat()
|
||||
* @see http://php.net/manual/streamwrapper.url-stat.php
|
||||
*/
|
||||
public function url_stat($uri, $flags);
|
||||
|
||||
/**
|
||||
* Support for opendir().
|
||||
*
|
||||
* @param $uri
|
||||
* A string containing the URI to the directory to open.
|
||||
* @param $options
|
||||
* Unknown (parameter is not documented in PHP Manual).
|
||||
*
|
||||
* @return bool TRUE on success.
|
||||
* @see http://php.net/manual/streamwrapper.dir-opendir.php
|
||||
*/
|
||||
public function dir_opendir($uri, $options);
|
||||
|
||||
/**
|
||||
* Support for readdir().
|
||||
*
|
||||
* @return string The next filename, or FALSE if there are no more files in the directory.
|
||||
* @see http://php.net/manual/streamwrapper.dir-readdir.php
|
||||
*/
|
||||
public function dir_readdir();
|
||||
|
||||
/**
|
||||
* Support for rewinddir().
|
||||
*
|
||||
* @return bool TRUE on success.
|
||||
* @see http://php.net/manual/streamwrapper.dir-rewinddir.php
|
||||
*/
|
||||
public function dir_rewinddir();
|
||||
|
||||
/**
|
||||
* Support for closedir().
|
||||
*
|
||||
* @return bool TRUE on success.
|
||||
* @see http://php.net/manual/streamwrapper.dir-closedir.php
|
||||
*/
|
||||
public function dir_closedir();
|
||||
}
|
||||
Reference in New Issue
Block a user