2erlei/fl/tools/factory.php

319 lines
7.3 KiB
PHP
Raw Normal View History

2019-09-22 14:53:30 +00:00
<?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;
}
}