@ 2014-04-08T14:04:17Z <?php
/**
* SETTINGS.
*
* Objects of class Settings are injected to factories
* as initiators of various classes.
*
* Process:
* - FUNCTIONS.PHP: Create object Settings().
* - FUNCTIONS.PHP: Set args by Settings:set().
* - FUNCTIONS.PHP: Create object Factory($settings).
* - CLASS-FACTORY.PHP: Create functionality objects according to settings.
* - CLASS-WORKER.PHP: Parent functionality.
*
* @author Petr Cibulka <cibulka.me@gmail.com>
* @link http://cibulka.me
*
* @package Cibulka_Framework\Architecture
* @since 1.0
* @version 1.0
*
* @filesource
*/
// ----------------------------------------------------------------------------------
/**
* SETTINGS CLASS.
*
* @used-by Factory()
* @package Cibulka_Framework\Architecture
*
*/
// ----------------------------------------------------------------------------------
class Settings {
private $prefix = '';
private $spec = [];
private $workers = [];
/**
* CONSTRUCTOR.
*
* Sets prefix. The rest is done by Settings::setters();
*
* @param string $prefix Sets prefix for all chained classes.
*
*/
function __construct($prefix) {
$this->prefix = $prefix;
}
// --------------------------------------------------------------------------
/**
* SETTER.
*
* Note: If unique worker needed, leave ID blank
* => arg TYPE will act both like type of functionality AND unique ID.
*
* @param string $type Sets type of functionality. If class should be unique, acts as ID as well.
* @param string $id
* @param array $args Args are later validated by Worker().
*
*/
public function set($type,$id='',$args='') {
/*ID*/
$id = $this->get_id($type,$id);
if (!$id) { return false; }
/*SPEC*/
$spec = $this->create_spec($type,$id,$args);
/*VALIDATION & TRANSLATION*/
$v = new Validator();
try {
// SPEC: Validation
$v->spec_validate($type);
// ARGS: Translation
$v->args_translate($args,$type);
// ARGS: Validation
$v->args_validate($args,$type);
} catch (Exception $e) {
$message = $e->getMessage();
$line = $e->getLine();
$file = $e->getFile();
$trace = $e->getTrace();
?>
<table>
<tr>
<th colspan="2"><?php echo $message; ?></th>
</tr><tr>
<td>Line: <?php echo $line; ?></td>
<td>File: <?php echo $file; ?></td>';
</tr><tr>
</tr><tr>
<td colspan="2">Trace: <?php echo $trace; ?></td>
</tr>
</table>
<?php
return false;
}
/*ARGS*/
$this->workers[$id]['type'] = $type;
$this->workers[$id]['args'] = (!empty($args)) ? $args : array();
/*TEST*/
//helper::printr($this);
}
// --------------------------------------------------------------------------
private function get_id($type,$id) {
$id = (!empty($id)) ? $id : $type;
// Error
// TODO: Create proper exception
if (array_key_exists($id,$this->workers)) {
$text = 'Worker with ID '.$id.' already exists.';
$error = new Error($this,$text);
trigger_error();
return false;
}
return $id;
}
private function create_spec($type,$id,$args) {
$spec_name = ucfirst($this->prefix).'_'.ucfirst($type).'_Spec';
// Initiate, if not already
if (!array_key_exists($type, $this->spec)) {
$this->spec[$type] = new $spec_name($type,$id);
}
return $spec_name;
}
// --------------------------------------------------------------------------
private function spec_validate($type) {
$spec = $this->spec[$type];
foreach ($spec as $spec_term => $spec_row) {
// Conflicting spec keys
// req & def
if (array_key_exists('req',$spec_row)) {}
// wrong type to check
if (!empty($spec_row['type'])) {
$type = helper::str_to_array($spec_row['type']);
$type_supported = array('boolean','integer','double','string','array','object','resource','null','file');
$type_unsupported = array_diff($type,$type_supported);
if ($type_unsupported) {
trigger_error('Unsupported type!');
return false;
}
}
// wrong count
if (!empty($spec_row['count'] && is_string($spec_row['count'])) {
// max & min
// range
}
}
return true;
}
private function args_translate($args,$type) {
$spec = $this->spec[$type];
foreach ($spec as $spec_term => $spec_row) {
/*KEYS & DEF values*/
$spec_def_value = (!empty($property_row['def'])) ? $property_row['def'] : null;
// SET
if (!empty($this->args[$spec_term])) {
continue;
} else {
$this->args[$spec_term] = $spec_def_value;
}
}
return true;
}
private function args_validate($args,$type) {
$spec = $this->spec[$type]->get_all();
/*SHOULD WE VALIDATE?*/
if (!$spec) {
// ARGS disabled & Not set => ok
if (empty($this->args)) {
return;
}
// ARGS disabled & set => not ok
else {
trigger_error('ARGS are not allowed');
}
}
/*UNSUPPORTED SPEC*/
$args_terms_unsupported = array_diff_key($this->args, $spec);
if ($args_terms_unsupported) {
trigger_error('Unsupported keys: '.implode(', ', $args_terms_unsupported));
return false;
}
/*LOOP THROUGH SPEC*/
foreach ($spec as $spec_term => $spec_row) {
$user_value = $this->args[$spec_term];
// ERROR: Required keys missing
$req = $spec_row['req'];
if ($req && empty($user_value)) {
trigger_error('Required ARG '.$spec_term.' is empty.');
return false;
}
// CONTINUE if $user_val empty
if (empty($user_value)) { continue; }
// ERROR: Count
if (!empty($spec_row['count'])) {
$user_count = count(helper::str_to_array($user_value));
$count_error = $this->user_val_count($user_count,$spec_row['count']);
if ($count_error) {
trigger_error('Wrong count on '.$spec_term);
}
}
// ERROR: TYPE: File
if (!empty($spec_row['type']) && !is_array($spec_row['type']) && 'file' === $spec_row['type']) {
// Escape type checking later
$type_escape = true;
// Error: File is not a string
$user_value_is_string = is_string($user_value);
if (!$user_value_is_string) {
trigger_error('File must be string.');
return false;
}
// Error: File does not exist
$file_exists = $this->check_file($user_value);
if (!$file_exists) {
trigger_error('File has weird SRC.');
return false;
}
}
// ERROR: TYPE: Common types
if (!empty($spec_row['type'] && !$type_escape) {
$user_value_type_supported = in_array(gettype($user_value),helper::str_to_array($spec_types));
if (!$user_value_type_supported) {
trigger_error('Value type is not supported');
return false;
}
}
// ERROR: VALUES
if (!empty($spec_row['vals'])) {
$user_val_unsupported = array_diff(helper::str_to_array($user_val),$spec_val);
if ($user_val_unsupported) {
trigger_error('Value is unsupported');
return false;
}
}
}
return true;
}
}
// ------------------------------------------------------------------------------
interface Spec_Interface {
public function set($property,$key,$value='');
public function get($property);
}
interface Spec_Interface_Child {
public function spec_set();
}
abstract class Spec implements Spec_Interface {
protected $worker = array(
'type' => '',
'id' => ''
);
// --------------------------------------------------------------------------
function __construct($type,$id) {
$this->worker['type'] = $type;
$this->worker['id'] = $id;
/*SPEC*/
// Sets default values & allowed values
if (method_exists($this,'spec_set')) {
try {
// parent
$this->spec_set();
// child
if (method_exists($this,'spec_set_child')) {
$this->spec_set_child();
}
} catch (Exception $e) {
}
}
}
// --------------------------------------------------------------------------
// TODO: Exceptions
function set($property,$spec_key,$value='') {
$allowed_keys = array('def','vals');
if (!in_array($spec_key,$allowed_keys)) {
trigger_error('TYPES accepted: '.implode(', ', $allowed_keys).'. Type provided: <b>'.$spec_key.'</b>.');
}
if (property_exists($this,$property)) {
$this->{$property}[$spec_key] = $value;
} else {
trigger_error('Property <b>'.$spec_key.'</b> is not supported.');
}
}
function get($property) {
if (property_exists($this,$property)) {
return $this->{$property};
} else {
trigger_error('Property '.$property.' does not exist.');
}
}
function get_all() {
return get_object_vars($this);
}
}
abstract class Scripts_Spec extends Spec implements Spec_Interface_Child {
protected
$script_type = array(
'req' => true,
'num' => 1,
'vals' => array('wp','admin','login')
);
protected
$load = array(
'req' => false,
'num' => 1,
'type' => array('string','object'),
'vals' => array('post_edit')
);
protected
$autoload = array(
'req' => false,
'num' => 1,
'type' => 'boolean',
'def' => false
);
protected
$local = array(
'req' => false,
'num' => 1,
'type' => 'boolean',
'def' => true
);
protected
$id = array(
'req' => false,
'num' => 1,
'type' => 'string',
'def' => ''
);
protected
$src = array(
'req' => false,
'num' => 1,
'type' => 'string'
);
protected
$deps = array(
'req' => false,
'num' => '',
'type' => array('string','array')
);
protected
$ver = array(
'req' => false,
'num' => 1,
'type' => 'string'
);
function spec_set() {
// ID > Def: id of worker
$this->set('id','def',$this->worker['id']);
}
}
class Scripts_Js_Spec extends Scripts_Spec {
}
class Scripts_Css_Spec extends Scripts_Spec {
}
?>
Enable javascript to submit You have javascript disabled. You will not be able to edit any code.
Output for 5.4.0 - 5.4.27 Parse error: syntax error, unexpected '&&' (T_BOOLEAN_AND), expecting ')' in /in/sqm0o on line 166
Process exited with code 255 . Output for 5.1.0 - 5.1.6 , 5.2.0 - 5.2.17 , 5.3.0 - 5.3.28 Parse error: syntax error, unexpected '[' in /in/sqm0o on line 41
Process exited with code 255 . Output for 5.0.0 - 5.0.5 Parse error: parse error, unexpected '[' in /in/sqm0o on line 41
Process exited with code 255 . Output for 4.4.2 - 4.4.9 Parse error: syntax error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in /in/sqm0o on line 40
Process exited with code 255 . Output for 4.3.0 - 4.3.1 , 4.3.5 - 4.3.11 , 4.4.0 - 4.4.1 Parse error: parse error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in /in/sqm0o on line 40
Process exited with code 255 . Output for 4.3.2 - 4.3.4 Parse error: parse error, expecting `T_OLD_FUNCTION' or `T_FUNCTION' or `T_VAR' or `'}'' in /in/sqm0o on line 40
Process exited with code 255 . preferences:dark mode live preview
224.17 ms | 1395 KiB | 117 Q