319 lines
7.3 KiB
PHP
319 lines
7.3 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
* Federleicht-Factory
|
||
|
*
|
||
|
* Sammlung aller Objekterzeugungsmethoden, um einen
|
||
|
* zentralen Ort dafür zu haben
|
||
|
*
|
||
|
* @package federleicht
|
||
|
* @subpackage base
|
||
|
*/
|
||
|
class fl_factory {
|
||
|
/**
|
||
|
* Referenzen auf externe Objekte
|
||
|
*/
|
||
|
protected $registry = null;
|
||
|
protected $data_access = null;
|
||
|
protected $structures = null;
|
||
|
protected $inflector = null;
|
||
|
|
||
|
/**
|
||
|
* Konstruktor
|
||
|
*/
|
||
|
public function __construct() {
|
||
|
$this->registry = fl_registry::getInstance();
|
||
|
$this->structures = new fl_data_structures();
|
||
|
|
||
|
$lang = $this->registry->get('config', 'lang');
|
||
|
$this->inflector = new fl_inflector($lang['application']);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Datenzugriff setzen
|
||
|
*
|
||
|
* @param data_access $data_access
|
||
|
*/
|
||
|
public function set_data_access(data_access $data_access) {
|
||
|
$this->data_access = $data_access;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Eine Federleicht-interne Klasse erzeugen und zurückgeben
|
||
|
*
|
||
|
* @todo verbessern, indem die verschiedenen Klassen mit den entsprechenden Parametern versorgt werden oder an passende Methoden deligiert wird...
|
||
|
* @param string $class_name
|
||
|
* @return mixed
|
||
|
*/
|
||
|
public function create($class_name) {
|
||
|
$class = "fl_{$class_name}";
|
||
|
return new $class();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Weiteres Model holen
|
||
|
*
|
||
|
* Nach Möglichkeit wird das Model aus der Registry geholt.
|
||
|
* @pattern IdentityMap
|
||
|
*
|
||
|
* @throws LogicException Wenn keine Datenzugriffsklasse gesetzt wurde.
|
||
|
*
|
||
|
* @param string $modul Name des Moduls, aus dem das Model geholt wird.
|
||
|
* @return fl_model
|
||
|
*/
|
||
|
public function get_model($modul) {
|
||
|
if ( $this->registry->get('loaded_model_'.$modul) === FALSE ) {
|
||
|
if ( $this->data_access == null ) {
|
||
|
throw new LogicException('Der Factory ist keine Datenzugriffsklasse bekannt: Mit set_data_access(data_access) setzen!');
|
||
|
}
|
||
|
|
||
|
$this->load_module($modul);
|
||
|
|
||
|
$model_name = 'app_' . $modul . '_model';
|
||
|
$get_model = new $model_name(
|
||
|
$this->data_access,
|
||
|
$this,
|
||
|
(string) $this->registry->get('path', 'module'));
|
||
|
|
||
|
$this->registry->set('loaded_model_'.$modul, $get_model);
|
||
|
}
|
||
|
|
||
|
return $this->registry->get('loaded_model_'.$modul);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Klasse holen
|
||
|
*
|
||
|
* @param string $class
|
||
|
* @param array $options (dynamic)
|
||
|
* @return object
|
||
|
*/
|
||
|
public function get_class($class) {
|
||
|
if ( strpos($class, '/') === false) {
|
||
|
throw new InvalidArgumentException('Klassenname muss in der Form modul/class angegeben werden.');
|
||
|
} else {
|
||
|
list($modul, $class_name) = explode('/', $class, 2);
|
||
|
}
|
||
|
|
||
|
$this->load_class($modul, $class_name);
|
||
|
|
||
|
$instance = new $class_name();
|
||
|
if ( func_num_args() > 1 ) {
|
||
|
$args = func_get_args();
|
||
|
array_shift($args);
|
||
|
$options = array_values($args);
|
||
|
|
||
|
$instance->set_options($options);
|
||
|
}
|
||
|
|
||
|
return $instance;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Activerecord-Klasse holen
|
||
|
*
|
||
|
* Nach Möglichkeit wird der Record aus der Registry geholt.
|
||
|
* @pattern IdentityMap
|
||
|
*
|
||
|
* @throws InvalidArgumentException Wenn der erste Parameter keinen Slash enthält
|
||
|
*
|
||
|
* @param string $class
|
||
|
* @param int $id
|
||
|
* @param array $data
|
||
|
* @return fl_data_structures_activerecord
|
||
|
*/
|
||
|
public function get_ar_class($class, $id = 0, array $data = array()) {
|
||
|
if ( strpos($class, '/') === false) {
|
||
|
throw new InvalidArgumentException('Klassenname muss in der Form modul/class angegeben werden.');
|
||
|
} else {
|
||
|
list($modul, $class_name) = explode('/', $class, 2);
|
||
|
}
|
||
|
|
||
|
$this->load_structure('activerecord');
|
||
|
$this->load_class($modul, $class_name);
|
||
|
|
||
|
$data = (array) $data;
|
||
|
if (!empty($data)) {
|
||
|
$loaded = true;
|
||
|
} else {
|
||
|
$loaded = false;
|
||
|
$data += array('id'=>$id);
|
||
|
}
|
||
|
|
||
|
if ( $this->is_structure($modul, $class_name) ) {
|
||
|
$data_structure = $this->get_structure($modul.'/'.$class_name, $data);
|
||
|
} else {
|
||
|
$data_structure = $this->get_structure('data', $data);
|
||
|
}
|
||
|
|
||
|
$identifier = "{$class_name}_{$id}";
|
||
|
|
||
|
if ( !$this->registry->is_set('loaded_record_'.$identifier) ) {
|
||
|
$instance = new $class_name(
|
||
|
$this->data_access,
|
||
|
$this->inflector->plural($class_name),
|
||
|
$id,
|
||
|
$data_structure,
|
||
|
$loaded
|
||
|
);
|
||
|
|
||
|
$this->registry->set('loaded_record_'.$identifier, $instance);
|
||
|
}
|
||
|
|
||
|
return $this->registry->get('loaded_record_'.$identifier);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Datenstruktur holen
|
||
|
*
|
||
|
* @param string $wanted_structure
|
||
|
* @param array $data
|
||
|
* @return data_wrapper
|
||
|
*/
|
||
|
public function get_structure($wanted_structure, $data = null) {
|
||
|
return $this->structures->get($wanted_structure, $data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Helfermodul holen
|
||
|
*
|
||
|
* @param string $wanted_helper
|
||
|
* Weitere Parameter werden übernommen und an den Konstruktor weitergegeben.
|
||
|
*
|
||
|
* @return object
|
||
|
*/
|
||
|
public function get_helper($wanted_helper) {
|
||
|
$this->load_helper($wanted_helper);
|
||
|
|
||
|
switch ( func_num_args() ) {
|
||
|
case 3:
|
||
|
$f1 = func_get_arg(1);
|
||
|
$f2 = func_get_arg(2);
|
||
|
$helper = new $wanted_helper($f1, $f2);
|
||
|
break;
|
||
|
|
||
|
case 2:
|
||
|
$f1 = func_get_arg(1);
|
||
|
$helper = new $wanted_helper($f1);
|
||
|
break;
|
||
|
|
||
|
case 1:
|
||
|
default:
|
||
|
$helper = new $wanted_helper();
|
||
|
}
|
||
|
|
||
|
return $helper;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* ############# Funktionen zum Einlesen der entsprechenden Dateien ######
|
||
|
*/
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Datenstruktur einlesen
|
||
|
*
|
||
|
* @param string $wanted_structure
|
||
|
*/
|
||
|
public function load_structure($wanted_structure) {
|
||
|
if ( strpos($wanted_structure, '/') === false ) {
|
||
|
$this->structures->load_structure($this->structures->built_in, $wanted_structure);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Klassendatei einlesen
|
||
|
*
|
||
|
* @param string $modul
|
||
|
* @param string $class
|
||
|
*/
|
||
|
public function load_class($modul, $class) {
|
||
|
require_once $this->registry->get('path', 'module') . $modul . '/classes/'.$class.'.php';
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Aufruf eines Helfermodul
|
||
|
*
|
||
|
* Der Quellcode eines namentlich benannten
|
||
|
* Helfermoduls wird eingelesen.
|
||
|
*
|
||
|
* @throws OutOfRangeException Wenn die gewünschte Helperklasse nicht existiert
|
||
|
*
|
||
|
* @param string $wanted Name des gewünschten Helfermoduls
|
||
|
* @return boolean
|
||
|
*/
|
||
|
public function load_helper($wanted) {
|
||
|
if ( !in_array( $wanted, $this->registry->get('helpers') ) ) {
|
||
|
throw new OutOfRangeException("Helperklasse {$wanted} nicht gefunden");
|
||
|
}
|
||
|
|
||
|
include_once $this->registry->get('path', 'helper') . $wanted . '.php';
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Moduldatei einlesen
|
||
|
*
|
||
|
* @throws OutOfRangeException Wenn die passende Moduldatei nicht existiert
|
||
|
* @param string $modul
|
||
|
*/
|
||
|
public function load_module($modul) {
|
||
|
$modul_path = $this->registry->get('path', 'module') . $modul . '/model.php';
|
||
|
|
||
|
if ( !in_array($modul, $this->registry->get('modules')) ) {
|
||
|
$common_path = $this->registry->get('path', 'module') . 'common/models/'.$modul.'.php';
|
||
|
|
||
|
if ( file_exists( $common_path ) ) {
|
||
|
$modul_path = $common_path;
|
||
|
} else {
|
||
|
throw new OutOfRangeException("Modul {$modul} wurde nicht gefunden");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
require_once $modul_path;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/**
|
||
|
* ########## Funktionen, die auf Existenz der entsprechenden Dateien ####
|
||
|
*/
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Pruefung, ob Datenstruktur existiert
|
||
|
*
|
||
|
* @param string $modul
|
||
|
* @param string $class
|
||
|
* @return boolean
|
||
|
*/
|
||
|
public function is_structure($modul, $class) {
|
||
|
return $this->structures->exists($modul, $class);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* ########## interne Funktionen #########################################
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* Klassenidentifikator parsen
|
||
|
*
|
||
|
* @param string $class
|
||
|
* @return array
|
||
|
* @access private
|
||
|
*/
|
||
|
protected function parse_class_name($class) {
|
||
|
$common = 'common';
|
||
|
$builtin = 'builtin';
|
||
|
|
||
|
if ( strpos($class, '/') === false) {
|
||
|
$result = array($common, $class);
|
||
|
} else {
|
||
|
$result = explode('/', $class, 2);
|
||
|
}
|
||
|
|
||
|
return $result;
|
||
|
}
|
||
|
}
|