Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 2 [3]

Author Topic: Discussions on ideas for a core framework  (Read 4508 times)

Keyrocks

  • Doug
  • ULTIMATE member
  • ******
  • Karma: 449
  • Posts: 6019
  • Semantically Challenged
    • snews.ca
Re: Discussions on ideas for a core framework
« Reply #30 on: August 18, 2012, 04:16:12 PM »

Another link, explaining OOP for non-techies using the cars & trucks as objects.

And from a guy who thinks his difficulty understanding OOP may be due to a birth defect (or something...  ;D  OOP Explained.
« Last Edit: August 18, 2012, 04:20:36 PM by Keyrocks »
Logged
Do it now... later may not come.
-------------------------------------------------------------------------------------------------
sNews 1.6 MESU | sNews 1.6 MEMU

nukpana

  • Hero Member
  • *****
  • Karma: 71
  • Posts: 663
Re: Discussions on ideas for a core framework
« Reply #31 on: August 18, 2012, 07:42:36 PM »

@ doug, fred
Google is your friend for this but the 2 links on the first page results are:
Definition by Oracle/Java: http://docs.oracle.com/javase/tutorial/java/concepts/index.html
OOP with Python (definition and a pet too!): http://net.tutsplus.com/tutorials/python-tutorials/python-from-scratch-object-oriented-programming/

Another dog one (I like dogs..) : http://www.javaranch.com/campfire/StoryPoly.jsp
Another explaination: http://stackoverflow.com/questions/84125/oo-php-explanation-for-a-braindead-n00b/94224#94224
« Last Edit: August 18, 2012, 07:44:21 PM by nukpana »
Logged

Keyrocks

  • Doug
  • ULTIMATE member
  • ******
  • Karma: 449
  • Posts: 6019
  • Semantically Challenged
    • snews.ca
Re: Discussions on ideas for a core framework
« Reply #32 on: August 18, 2012, 10:50:19 PM »

Thanks Jason, useful pages +.
My apology for just googling somewhat randomly.  :)
OOP PHP for Beginners by Jason Lengstorf (also @ NetTutsPlus) helped increase my understanding of using OOP with PHP a couple of notches this afternoon (though I ended up power-napping for 10 minutes while reading it).
« Last Edit: August 18, 2012, 10:56:41 PM by Keyrocks »
Logged
Do it now... later may not come.
-------------------------------------------------------------------------------------------------
sNews 1.6 MESU | sNews 1.6 MEMU

nukpana

  • Hero Member
  • *****
  • Karma: 71
  • Posts: 663
Re: Discussions on ideas for a core framework
« Reply #33 on: August 19, 2012, 12:03:29 AM »

Lol, yeah that one is long one and I wouldn't recommend unless you break it up into blocks that you will come back to (with an extra cup of coffee!)
Logged

philmoz

  • High flyer
  • ULTIMATE member
  • ******
  • Karma: 161
  • Posts: 1988
    • fiddle 'n fly
Re: Discussions on ideas for a core framework
« Reply #34 on: August 23, 2012, 10:36:04 PM »

I am like Fred, in that I see things more in straight lines start to finish, not as a great wad of string from which a results pops out of ;)

That said, I also agree with Jason... if the core functionality as the innermost layer doesn't require tweaking, then anything placed on top can be procedural.
Logged
Of all the things I have lost, it is my mind that I miss the most.

nukpana

  • Hero Member
  • *****
  • Karma: 71
  • Posts: 663
Re: Discussions on ideas for a core framework
« Reply #35 on: September 30, 2012, 07:03:31 AM »

For now, I think I am done with the base framework.  The harder part is the next layer of the application where the plugins interface with - As shown in an earlier example, I am not crazy about it... Anyway, on with the code.  Again, not too much different than before:

SQL (mysql):
Code: [Select]
CREATE TABLE plugins (
name VARCHAR(255) NOT NULL,
UNIQUE (name)
) ENGINE = InnoDB;

CREATE TABLE options (
name VARCHAR(255) NOT NULL,
value VARCHAR(255) NOT NULL,
INDEX (name),
UNIQUE (name)
) ENGINE = InnoDB;

config.php:
Code: [Select]
; <?php exit; ?>
; Database

; DSN: ex. mysql:host=localhost;dbname=dbName
; See the below for examples:
; mySQL: http://www.php.net/manual/en/ref.pdo-mysql.connection.php
; SQLite: http://www.php.net/manual/en/ref.pdo-sqlite.connection.php
; PostgreSQL: http://www.php.net/manual/en/ref.pdo-pgsql.connection.php
database.dsn = "mysql:host=localhost;port=8889;dbname=testCMS-00"

; Database User
database.user = "root"

; Database Password
database.pass = "root"

; Paths
path.languages = "app/lang"
path.extensions = "app/ext"
path.templates = "app/tpl"
path.admin = "app/admin"

; Rewrite - change to TRUE if mod_rewrite is installed
; removes ?/ from internal urls ie:
; http://localhost/cms/?/admin/post/2/edit rewrite.url = FALSE
; http://localhost/cms/admin/post/2/edit rewrite.url = TRUE
rewrite.url = "FALSE";

index.php
Code: [Select]
<?php

error_reporting(-1);

session_start();

#---------- Helper Functions ---------------------------------------------------

// Returns value from array[key]
// Based from https://wiki.php.net/rfc/functionarraydereferencing
// @return object on success, false on failure
function value($key, array $array) {
return isset($array[$key])
$array[$key]
false;
}

// Get values from an config (ini) file based on section/key
// @return object on success
function get_ini_value($key$file 'config.php') {
static $ini$array;
if( $ini !== $file ) {
$ini $file;
$array parse_ini_file($fileTRUE);
}
return value($key$array);
}

// PDO database connection wrapper
// @return object on success, dies on failure
function db() {
static $db;
if( !$db ) {
$db FALSE;
try {
$db = new PDO(
get_ini_value('database.dsn'),
get_ini_value('database.user'),
get_ini_value('database.pass')
);
} catch( PDOException $e ) {
die( $e->getMessage() );
}
}
return $db;
}

// From http://www.php.net/manual/en/function.strip-tags.php#62705
function strip_tags_deep($value) {
return is_array($value
array_map('strip_tags_deep'$value
strip_tags($value);
}

// Modified version of http://php.net/manual/en/function.ksort.php#105399
function ksort_recursive(array &$array) {
ksort$array );
foreach( $array as &$a ) {
if( is_array($a) ) {
ksort_recursive($a);
}
}
}

#---------- Registry Class -----------------------------------------------------

final class Registry {
private static 
$_data = array();

static function get$key ) {
if( isset(self::$_data[$key]) ) {
return self::$_data[$key];
}
}

static function set$key$value '' ) {
self::$_data[$key] = $value;
}
}

#---------- Observable & Observer classes --------------------------------------

class Observable {
private 
$_event,
$_observers = array();

final function attachObserver $observer ) {
$i array_search($observer$this->_observers);
if( $i === false ) {
$this->_observers[] = $observer;
}
}

final function createEvent$event ) {
$this->_event $event;
$this->_notify();
}

final function getEvent() {
return $this->_event;
}

final private function _notify() {
foreach( $this->_observers as $observer ) {
$observer->update$this );
}
}
}

interface Observer {
function updateObservable $subject );
}

#---------- AddOn Template -----------------------------------------------------

abstract class AddOn extends Observable {
protected 
$_active,
$_list = array();

abstract function load();
abstract function get();
abstract function process($str);

abstract protected function set($addon);
}

// Procedural helpers
function addon_init(AddOn $addon) {
$addon->load();
}

function addon_get(AddOn $addon) {
return $addon->get();
}

function addon_process(AddOn $addon$str) {
$addon->process($str);
}

#---------- Options CRUD Class ------------------------------------------------

final class Options {
private static
$_db,
$_data = array();

static function init$db ) {
self::$_db $db;
$sql 'SELECT name, value FROM options;';
foreach( self::$_db->query($sql) as $r ) {
self::$_data[$r['name']] = $r['value'];
}
}

static function get$key ) {
if( self::exists($key) ) {
return self::$_data[$key];
}
}

static function set$key$value ) {
if( self::exists($key) ) {
$sql "UPDATE options 
SET value = :value 
WHERE name = :key;"
;
} else {
$sql "INSERT INTO options 
VALUES(:key, :value);"
;
}
$sth self::$_db->prepare($sql);
$sth->execute(
array(
':key'   => $key,
':value' => $value
)
);
}

static function delete$key ) {
if( self::exists($key) ) {
$sql "DELETE 
FROM options 
WHERE name = :key;"
;
$sth self::$_db->prepare($sql);
$sth->execute(
array(
':key' => $key
)
);
}
}

static function exists$key ) {
return array_key_exists($keyself::$_data);
}
}
// Initialize options
Options::init(db());

// Procedural helpers
function get_option$value ) {
return Options::get$value );
}

function set_option$key$value ) {
Options::set$key$value );
}

function delete_option$key ) {
Options::delete$key );
}

#---------- Plugin Helper ------------------------------------------------------

define(
'EXT_PATH',
get_ini_value('path.extensions')
);

Registry::set('ext'
array(
'ext' => array(),
'hook'=> array()
)
);

function ext() {
return Registry::get('ext');
}

final class Extension {
private static
$_db,
$_data = array();

static function init$db ) {
self::$_db $db;
$sql 'SELECT name FROM plugins;';
foreach ( self::$_db->query($sql) as $r ) {
self::$_data[] = $r['name'];
}
}

static function get() {
return self::$_data;
}

static function add$name ) {
if( !self::exists($name) ) {
$sth self::$_db->query("
INSERT INTO plugins 
VALUES(:name);"
);
$sth->execute(
array(
':name' => $name
)
);
}
}

static function delete$name  ) {
if( self::exists($name) ) {
$sth self::$_db->query("
DELETE 
FROM plugins
WHERE name = :name;
"
);
$sth->execute(
array(
':name' => $name
)
);
}
}

static function exists$name ) {
return in_array$nameself::$_data ); 
}
}

final class Extensions extends AddOn {
function __construct() {
$this->_active Extension::get();
}

function load() {
foreach( $this->_active as $p ) {

$file EXT_PATH'/' .$p'/index.php';
$ini  EXT_PATH'/' .$p'/plugin.ini';

if( file_exists($file) && file_exists($ini) ) {
require( $file );

if( class_exists($p) ) {
$i = new $p;
$i->commit();
// Attach the observer
$this->attach($i);
}
}
}


function get() {
$dir opendir(EXT_PATH);
if( $dir ) {
while( false !== ($file readdir($dir)) ) {
if( 
   $file != '.' 
&& $file != '..' 
&& file_exists(EXT_PATH'/' .$file'/index.php')
&& file_exists(EXT_PATH'/' .$file'/plugin.ini')
) {

$this->_list[$file] = $this->data(
EXT_PATH'/' .$file'/plugin.ini'
);

if( in_array($file$this->_active) ) {
$this->_list[$file]['active'] = TRUE;
}
}
}
}
return $this->_list;
}

protected function data$file ) {
$array parse_ini_file($fileTRUE);
return strip_tags_deep($array);
}

protected function set$addon ) {
Extension::set$addon );
$this->createEvent('activated_' $addon);
}

protected function delete$addon ) {
Extension::delete$addon );
$this->createEvent('deactivated_' $addon);
}

function process$str ) { 
switch (true) {
case (strpos($str'activate') === ):
$this->set(substr($str'9'));
break;
case (strpos($str'deactivate') === ):
$this->delete(substr($str'11'));
break;
}
}
}

function extensions() {
static $exts;
if( !$exts ) {
$exts = new Extensions;
}
return $exts;
}

class Ext implements Observer {
protected 
$_name,
$_data = array();
private
$_ext
$_hook = array();

final function __construct() {
$this->_ext  ext();
$this->_name get_class($this);
$this->_data value(
$this->_name,
addon_get(extensions())
);
}

final function add$hook$callback$priority 10 ) {
$this->_hook[$hook][$priority][] = $callback;
}

final private function _check_requirements() {
if( isset($this->_data['plugin.dependencies']['requires']) ) {
$requirement $this->_data['plugin.dependencies']['requires'];

foreach( $requirement as $dep ) {
if( !isset($this->_ext['ext'][$dep]) ) {
$this->_data['req_error'] = TRUE;
}
}
}
}

final private function _set_hooks() {
if( isset($this->_data['plugin.hooks']) ) {
foreach( $this->_data['plugin.hooks'] as $hook => $calls ) {
if( is_array($calls) ) {
foreach( $calls as $k => $func ) {
$this->_ext['hook'][$hook][10][] = $func;
}
} else {
$this->_ext['hook'][$hook][10][] = $calls;
}
}
}

foreach ($this->_hook as $hook => $calls) {
foreach( $calls as $k => $call ) {
foreach( $call as $func ) {
$this->_ext['hook'][$hook][$k][] = $func;
}
}
}
}

final function commit() {
$this->_check_requirements();

if( method_exists($this'main') ) {
$this->main();
}

if(    !isset($this->_data['req_error']) 
|| $this->_data['req_error'] === FALSE 
) {

$this->_ext['ext'][$this->_name] = $this->_data;

$this->_set_hooks();
ksort_recursive($this->_ext['hook']);
}
Registry::set('ext'$this->_ext);
}

final function updateObservable $subject ) {
switch( $subject->getEvent() ) {
case( 'activated_' $this->_name ):
if( method_exists($this'install') ) {
$this->install();
}
break;

case( 'deactivated_' $this->_name  ):
if( method_exists($this'uninstall') ) {
$this->uninstall();
}
break;
}
}
}

function ext_commit(Ext $ext) {
$ext->commit();

// Log this transaction
$e ext();
$e['ext'][get_class($ext)]['internal_commit'] = TRUE;
Registry::set('ext'$e);
}

function exec_ext$hook$var NULL ) {
$ext ext();

if( isset($ext['hook'][$hook]) ) { 
foreach( $ext['hook'][$hook] as $k => $calls ) {
foreach( $calls as $func ) {
if( is_callable($func) ) {
$var $func($var);
}
}
}
}
return $var;
}

#---------- Template Helper ----------------------------------------------------

define
'TPL_PATH',
get_ini_value('path.templates'
);

final class Templates extends AddOn {
function __construct() {
$this->_active get_option('template');
}

function load() {
$file TPL_PATH .'/'$this->_active '/index.php';
$ini  TPL_PATH .'/'$this->_active '/template.ini';
if( file_exists($file) && file_exists($ini) ) {
require($file);
}


function get() {
$dir opendir(TPL_PATH);
if( $dir ) {
while( false !== ($file readdir($dir)) ) {
if( 
   $file != '.' 
&& $file != '..' 
&& file_exists(TPL_PATH'/' .$file'/index.php')
&& file_exists(TPL_PATH'/' .$file'/template.ini')
) {
$this->_list[$file] = $this->data(
TPL_PATH'/' .$file'/template.ini'
);
if( $file === $this->_active ) {
$this->_list[$file]['active'] = TRUE;
}
}
}
}
return $this->_list;
}

protected function data$file ) {
$array = array();
$array parse_ini_file($fileTRUE);
return strip_tags_deep($array);
}

protected function set$addon ) {
set_option'template'$addon );
}

function process$str ) {
if( strpos($str'activate') === ) {
$this->set(substr($str'9'));
}
}
}

function templates() {
static $tpls;
if( !$tpls ) {
$tpls = new Templates;
}
return $tpls;
}

#---------- Language Helper ----------------------------------------------------

define
'LANG_PATH'
get_ini_value('path.languages'
);

Registry::set('lang', array());

function lang() {
return Registry::get('lang');
}

final class Languages extends AddOn {
function __construct() {
$this->_active get_option('language');
}

function load() {
$array = array();
$file LANG_PATH .'/'$this->_active '.php';
if( file_exists($file) ) {
$array = require $file;
}
Registry::set('lang'$array);


function get() {
$dir opendir(LANG_PATH);
if ($dir) {
while (false !== ($file readdir($dir))) {
if (
$file != '.' && 
$file != '..' && 
file_exists(LANG_PATH .'/'$file)
) {
$filename basename($file'.php');
$this->_list[$filename] = array();

if( $filename === $this->_active ) {
$this->_list[$filename]['active'] = TRUE;
}
}
}
}
return $this->_list;
}

protected function set$addon ) {
set_option'language'$addon );
}

function process$str ) {
$this->set$str );
}
}
// initialize languages
addon_init(new Languages);

// Function to translate strings 
// Uses http://php.net/manual/en/function.strtr.php
// Do not translate placeholder
function __$string, array $args NULL ) {
$string value($stringlang())
value($stringlang())
$string;

return $args === null
$string
strtr($string$args);
}

#---------- Form Validator Class -----------------------------------------------

abstract class Validator {
protected 
$_errorMsg 'undefined';

    final function getError() {
     return $this->_errorMsg;
    }

abstract function validate($value);
}

final class Validate {
private 
$_data = array(),
$_errors = array();

function addValidator($fieldValidator $obj) {
$this->_data[$field][] = $obj;
return $this;
}

function isValid($array) {
$valid true;

foreach( $this->_data as $field => $objects ) {
foreach($objects as $i => $obj) {
if(  isset($array[$field]) 
&& !$obj->validate($array[$field]) 
) {

$valid false;
$this->_errors[] = array(
'field' => $field,
'error' => $obj->getError()
);
break;
}
}
}
return $valid;
}

function getErrors() {
return $this->_errors;
}
}

function get_validation_error($field, array $array) {
$exists false;
foreach( $array as $k => $v ) {
if(   isset($array[$k]['field']) 
&&  $array[$k]['field'] === $field 
) {
$exists true;
}
}
if( $exists ) {
return $array[$k]['error'];
}
}

#---------- URI Helpers --------------------------------------------------------

// Remove index.php, and duplicate slashes from $_SERVER['REQUEST_URI']
// Based on http://brandonwamboldt.ca/my-php-router-class-825/
function _prepare_uri() {
$uri $_SERVER['REQUEST_URI'];
$uri str_replacedirname($_SERVER['SCRIPT_NAME']), ''$uri );
$uri str_replace('index.php'''$uri);
$uri str_replace('?/'''$uri);
$uri preg_replace'/\/+/''/'$uri );
$uri ltrim$uri'/' );

return $uri;
}

function parse_uri($component null) {
$array = array();

$uri _prepare_uri();
$uri parse_url($uri);

if( isset($uri['path']) ) {
$uri['path'] = trim($uri['path'], '/');
$array['path'] = explode('/'$uri['path']);
}
if( isset($uri['query']) ) {
parse_str($uri['query'], $array['query']);
}

return isset($array[$component])
$array[$component]
$array;
}

function uri_part($num) {
return value($numparse_uri('path'));
}

function uri_qstr($key) {
return value($keyparse_uri('query'));
}

function build_url() {
$str  'http://' $_SERVER['HTTP_HOST'];
$str .= str_replace'index.php'''$_SERVER['SCRIPT_NAME'] );
$qs get_ini_value('rewrite.url') === TRUE
''
'?/';
$args func_get_args();

if( !empty($args[0]) ) {
$args implode('/'$args);
return $str $qs $args;
} else {
return $str;
}
}

#---------- Router Class -------------------------------------------------------

// Modified from http://brandonwamboldt.ca/my-php-router-class-825/
final class Router {
private 
$_callback,
$_params = array(),
$_routes = array(),
$_uri;

function __construct$uri ) {
$this->_uri $uri;
}

    function route$route$callback ) {
$route ltrim$route'/' );

// Custom, format: <:var_name|regex>
$route preg_replace
'/\<\:(.*?)\|(.*?)\>/'
'(?P<\1>\2)'
$route 
);

// Alphanumeric, format: <:var_name>
$route preg_replace
'/\<\:(.*?)\>/'
'(?P<\1>[A-Za-z0-9\-\_]+)'
$route 
);

// Numeric, format: <#var_name>
$route preg_replace
'/\<\#(.*?)\>/'
'(?P<\1>[0-9]+)'
$route 
);

// Wildcard (INCLUDING dir separators), format: <*var_name>
$route preg_replace
'/\<\*(.*?)\>/'
'(?P<\1>.+)'
$route 
);

// Wildcard (EXCLUDING dir separators), format: <!var_name>
$route preg_replace
'/\<\!(.*?)\>/',
'(?P<\1>[^\/]+)'
$route 
);

// Add regex for a full match or no match
$route '#^' $route '$#';

        // Add the route to our routing array
        $this->_routes[$route] = $callback;
}

    function execute() {
foreach ( $this->_routes as $route => $callback ) {
if ( preg_match$route$this->_uri$matches ) ) {
foreach ( $matches as $key => $match ) {
if ( is_string$key ) ) {
$this->_params[$key] = $match;
}
}
$this->_callback $callback;
}
}
    if ( $this->_callback === NULL) return;

if( is_callable($this->_callback) ) {
$fn $this->_callback;
$fn$this->_params );
}
}
}

function add_route($route$callback) {
$rtr = new Router(
implode('/'parse_uri('path'))
);
$rtr->route($route$callback);
$rtr->execute();
}

#---------- Admin Base Functions -----------------------------------------------

define(
'ADMIN'
isset($_SESSION['Logged_In'])
);

define(
'ADMIN_PATH',
get_ini_value('path.admin')
);

abstract class AdminModule extends Ext {
function register_admin_module() {
$this->_data['admin_module'][] = substr($this->_name5);
}
}

function registered_admin_modules() {
$modules = array();
foreach( value('ext'ext()) as $ext ) {
if( isset($ext['admin_module'][0]) ) {
$modules[] = strtolower(
$ext['admin_module'][0]
);
}
}
$modules array_flip($modules);
return $modules;
}

« Last Edit: September 30, 2012, 02:36:22 PM by nukpana »
Logged

nukpana

  • Hero Member
  • *****
  • Karma: 71
  • Posts: 663
Re: Discussions on ideas for a core framework
« Reply #36 on: February 25, 2013, 09:50:50 AM »

I stated here that I was working on a rewrite of this.  I will post some of the ideas/code:

Extension base:
The previous iteration shown in the above post was ok at the time, but needed to be refactored and things removed/re-purposed:

The basis of the code is a simple static Event class very similar to the code posted here and here

Code: [Select]
<?php

#---------- Event Class --------------------------------------------------------

class Event {
static private 
$_events = array();

final static function on$event$func$priority 10 ) {
if( is_callable($func) ) {
self::$_events[$event][$priority][] = $func;
}
ksort_recursive(self::$_events);
}

final static function trigger$event$var null ) {
if( isset(self::$_events[$event]) ) { 
foreach( self::$_events[$event] as $i => $calls ) {
foreach( $calls as $func ) {
if( is_callable($func) ) {
$var call_user_func($func$var);
}
}
}
}
return $var;
}
}

Now, the plugin API for users:
Code: [Select]
<?php

class 
Ext implements Observer {
private
$_name;

final function __construct() {
$this->_name get_class($this);
}

final function bind($event$func$priority 10) {
Event::on($event$func$priority);
}

final function commit() {
if( method_exists($this'main') ) {
$this->main();
}
}

final function updateObservable $subject ) {
$method '';
switch( $subject->getState() ) {
case( 'activated_' $this->_name ):
$method 'install';
break;

case( 'deactivated_' $this->_name  ):
$method 'uninstall';
break;
}
Event::on($subject->getState(), array($this$method));
}
}

Alot smaller and clearer than before.  I removed adding hook/callaback in the plugin.ini as I didn't feel it being needed, since you would still need to call the Ext class in your plugin - just add the call in the main() method. Also removed is the Registry class and ext() call to the Extension registry, since this got very code heavy trying to process all of the information in and out of the array.  Now the extensions are managed by the Extensions class and the hook/callbacks are managed by the Event class.  The Registry was a good idea for a future logger addon, but again, for a core system, was this really needed at this point?

The other functionality went to the Event class (sorting) & Extensions class (requirements):
Code: [Select]
<?php

final class 
Extensions extends AddOn {
private 
$_db;

function __construct() {
$this->_db db();
$this->_init();
}

private function _init() {
$this->_active = array();
$sql 'SELECT name 
FROM plugins;'
;
foreach ( $this->_db->query($sql) as $r ) {
$this->_active[] = $r['name'];
}
}

function load() {
foreach( $this->_active as $ext ) {
$file $this->_requiredFiles($ext);

$met_requirements false;
if( file_exists($file['index']) && file_exists($file['ini']) ) {

$met_requirements $this->_checkRequirements($file['ini']);
if( $met_requirements === true ) {
require( $file['index'] );

if( class_exists($ext) ) {
$i = new $ext;
$i->commit();
$this->attach($i);
}
}
}
}


function parse() {
$dir opendir(EXT_PATH);
if( $dir ) {
while( false !== ($ext readdir($dir)) ) {
$file $this->_requiredFiles($ext);

if(    $file != '.' 
&& $file != '..' 
&& file_exists($file['index'])
&& file_exists($file['ini'])
) {

$this->_list[$ext] = $this->data($file['ini']);

if( in_array($ext$this->_active) ) {
$this->_list[$ext]['active'] = TRUE;
}
}
}
}
return $this->_list;
}

protected function data$file ) {
$array parse_ini_file($fileTRUE);
return strip_tags_deep($array);
}

protected function set$addon ) {
if( !$this->exists($addon) ) {
$sth $this->_db->query("
INSERT INTO plugins 
VALUES(:name);"
);
$sth->execute(array(':name' => $addon));
}
}

protected function delete$addon ) {
if( $this->exists($addon) ) {
$sth $this->_db->query("
DELETE 
FROM plugins
WHERE name = :name;"
);
$sth->execute(array(':name' => $addon));
}
}

function process$str ) {
$addon '';
switch (true) {
// Ex: activate_Extension
case (strpos($str'activate') === ):
$addon substr($str'9');

$this->set($addon);
// Set observable event "activated_$addon"
$this->setState('activated_' $addon);
break;
// Ex: deactivate_Extension
case (strpos($str'deactivate') === ):
$addon substr($str'11');

$this->delete($addon);
// Set observable event "deactivated_$addon"
$this->setState('deactivated_' $addon);
break;
}
}

function exists$name ) {
return in_array($name$this->_active); 
}

private function _checkRequirements$file ) {
$is_met true;
$data $this->data($file);
if( isset($data['plugin.dependencies']['requires']) ) {
$requirement $data['plugin.dependencies']['requires'];

foreach( $requirement as $dep ) {
if( !in_array($dep$this->_active) ) {
$is_met false;
}
}
}
return $is_met;
}

private function _requiredFiles$extName ) {
return array(
"index" => EXT_PATH'/' .$extName'/index.php',
"ini" => EXT_PATH'/' .$extName'/plugin.ini'
);
}
}


The observer class is redone slightly to incorporate the Event::trigger method:
Code: [Select]
<?php

#---------- Observable & Observer classes --------------------------------------

interface Observer {
function updateObservable $subject );
}

class Observable {
private 
$_state,
$_observers = array();

final function attachObserver $observer ) {
$i array_search($observer$this->_observers);
if( $i === false ) {
$this->_observers[] = $observer;
}
}

final function notify() {
foreach( $this->_observers as $observer ) {
$observer->update$this );
}
}

final function setState$state ) {
$this->_state $state;
$this->notify();

Event::trigger$this->_state );
}

final function getState() {
return $this->_state;
}
}

I noted removal of the Registry class also effects the Language functionality slightly, including the removal of the strtr function, which, upon reviewing some of the sNews language strings, didn't really need this.. (yet):
Code: [Select]
<?php

final class 
Languages extends AddOn {
private
$_data = array();

function __construct() {
$this->_active Options::get('language');
}

function load() {
$array = array();
$file LANG_PATH .'/'$this->_active '.php';
if( file_exists($file) ) {
$this->_data = require $file;
}


function parse() {
$dir opendir(LANG_PATH);
if ($dir) {
while (false !== ($file readdir($dir))) {
if (   $file != '.' 
&& $file != '..' 
&& file_exists(LANG_PATH .'/'$file)
) {
$filename basename($file'.php');
$this->_list[$filename] = array();

if( $filename === $this->_active ) {
$this->_list[$filename]['active'] = TRUE;
}
}
}
}
return $this->_list;
}

protected function set$addon ) {
Options::set'language'$addon );
}

function process$str ) {
$this->set$str );
}

function getData() {
return $this->_data;
}
}

// Languages class wrapper
// Methods to be used by *_addon procedural functions
function languages() {
static $lang;
if( !$lang ) {
$lang = new Languages;
}
return $lang;
}

function lang() {
return languages()->getData();
}

function __$string, array $args NULL ) {
return value($stringlang())
value($stringlang())
$string;
}

« Last Edit: February 25, 2013, 11:32:47 AM by nukpana »
Logged
Pages: 1 2 [3]