parent
49cd813cde
commit
07976216ba
|
@ -1,6 +1,7 @@
|
|||
.gitattributes export-ignore
|
||||
.gitignore export-ignore
|
||||
.gitlab_ci.yml export-ignore
|
||||
.travis.yml export-ignore
|
||||
tests/ export-ignore
|
||||
CI/ export-ignore
|
||||
Application/ export-ignore
|
|
@ -20,14 +20,14 @@
|
|||
},
|
||||
"suggest": {
|
||||
"smarty/smarty": "Allows using Smarty in templates",
|
||||
"latte/latte": "Allows using Latte in templates"
|
||||
"latte/latte": "Allows using Latte in templates",
|
||||
"tracy/tracy": "Allows for extensive debugging"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "5.3.*",
|
||||
"apigen/apigen": "^4.1",
|
||||
"mikey179/vfsStream": "1.1.*",
|
||||
"smarty/smarty": "~3.1",
|
||||
"tracy/tracy": "*",
|
||||
"latte/latte": "*"
|
||||
},
|
||||
"autoload": {
|
||||
|
|
|
@ -45,22 +45,22 @@ use FuzeWorks\Event;
|
|||
class ModelLoadEvent extends Event
|
||||
{
|
||||
/**
|
||||
* The directory the model gets loaded from.
|
||||
* The directories the model can get loaded from.
|
||||
*
|
||||
* @var string|null
|
||||
* @var array
|
||||
*/
|
||||
public $directory = null;
|
||||
public $directories = array();
|
||||
|
||||
/**
|
||||
* The name of the model to be loaded.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $model = null;
|
||||
public $modelName = null;
|
||||
|
||||
public function init($model, $directory)
|
||||
public function init($modelName, $directories)
|
||||
{
|
||||
$this->model = $model;
|
||||
$this->directory = $directory;
|
||||
$this->modelName = $modelName;
|
||||
$this->directories = $directories;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,8 @@ namespace FuzeWorks;
|
|||
/**
|
||||
* Abstract class ControllerAbstract.
|
||||
*
|
||||
* At this point does nothing, can be extended in the future to allow special controller functions
|
||||
* Extends all controllers to use the Factory.
|
||||
* Factory should in the future be replaced with a DI container
|
||||
*
|
||||
* @author Abel Hoogeveen <abel@techfuze.net>
|
||||
* @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net)
|
||||
|
|
|
@ -1,112 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* FuzeWorks.
|
||||
*
|
||||
* The FuzeWorks MVC PHP FrameWork
|
||||
*
|
||||
* Copyright (C) 2015 TechFuze
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author TechFuze
|
||||
* @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net)
|
||||
* @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/)
|
||||
* @license http://opensource.org/licenses/GPL-3.0 GPLv3 License
|
||||
*
|
||||
* @link http://fuzeworks.techfuze.net
|
||||
* @since Version 0.0.1
|
||||
*
|
||||
* @version Version 0.0.1
|
||||
*/
|
||||
|
||||
namespace FuzeWorks;
|
||||
|
||||
/**
|
||||
* Interface for a Module that gives abstract model types
|
||||
* A model server must contain the methods from this interface in order to correctly serve models.
|
||||
*
|
||||
* @author Abel Hoogeveen <abel@techfuze.net>
|
||||
* @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net)
|
||||
*/
|
||||
interface ModelServer
|
||||
{
|
||||
public function giveModel($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract class Model.
|
||||
*
|
||||
* Abstract for a model data representation, loads the correct parent type
|
||||
*
|
||||
* @author Abel Hoogeveen <abel@techfuze.net>
|
||||
* @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net)
|
||||
*/
|
||||
abstract class Model
|
||||
{
|
||||
/**
|
||||
* The parent class holder object
|
||||
* Requests get redirected to this class.
|
||||
*
|
||||
* @var Parent Object
|
||||
*/
|
||||
private $parentClass;
|
||||
|
||||
/**
|
||||
* Set the type of this model. Eg, use techfuze/databasemodel and Databasemodel to get a SQL connected model.
|
||||
*
|
||||
* @param string Module_name, the name of the module where the model can be found
|
||||
* @param string Model_type, model type to return
|
||||
*/
|
||||
protected function setType($module_name, $model_type)
|
||||
{
|
||||
$mod = Modules::get($module_name);
|
||||
$this->parentClass = $mod->giveModel($model_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a value from the model class.
|
||||
*
|
||||
* @param Any key
|
||||
*
|
||||
* @return Any value from the model class
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
return $this->parentClass->$name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a value in the model class.
|
||||
*
|
||||
* @param Any key
|
||||
* @param Any value
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
{
|
||||
$this->parentClass->$name = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls a function in the model class.
|
||||
*
|
||||
* @param string function_name
|
||||
* @param array values
|
||||
*
|
||||
* @return Function return
|
||||
*/
|
||||
public function __call($name, $params)
|
||||
{
|
||||
return call_user_func_array(array($this->parentClass, $name), $params);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
/**
|
||||
* FuzeWorks.
|
||||
*
|
||||
* The FuzeWorks MVC PHP FrameWork
|
||||
*
|
||||
* Copyright (C) 2015 TechFuze
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author TechFuze
|
||||
* @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net)
|
||||
* @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/)
|
||||
* @license http://opensource.org/licenses/GPL-3.0 GPLv3 License
|
||||
*
|
||||
* @link http://fuzeworks.techfuze.net
|
||||
* @since Version 0.0.1
|
||||
*
|
||||
* @version Version 0.0.1
|
||||
*/
|
||||
|
||||
namespace FuzeWorks;
|
||||
|
||||
/**
|
||||
* Abstract class ModelAbstract.
|
||||
*
|
||||
* Extends all models to use the Factory.
|
||||
* Factory should in the future be replaced with a DI container
|
||||
*
|
||||
* @author Abel Hoogeveen <abel@techfuze.net>
|
||||
* @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net)
|
||||
*/
|
||||
abstract class ModelAbstract extends Factory
|
||||
{
|
||||
}
|
|
@ -36,77 +36,165 @@ use FuzeWorks\Exception\ModelException;
|
|||
/**
|
||||
* Models Class.
|
||||
*
|
||||
* Simple loader class for MVC Models. Typically loads models from Application/Models unless otherwise specified.
|
||||
* If a model is not found, it will load a DatabaseModel type which will analyze the database and can directly be used.
|
||||
* Simple loader class for MVC Models.
|
||||
* Typically loads models from Application/Models unless otherwise specified.
|
||||
*
|
||||
* If a model is not found, it will load a DatabaseModel type which will
|
||||
* analyze the database and can directly be used.
|
||||
*
|
||||
* @author Abel Hoogeveen <abel@techfuze.net>
|
||||
* @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net)
|
||||
*/
|
||||
class Models
|
||||
{
|
||||
/**
|
||||
* Array of all the loaded models.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $models_array = array();
|
||||
|
||||
/**
|
||||
* Array of all the existing model types (classes).
|
||||
*
|
||||
* @var array
|
||||
* Paths where Models can be found.
|
||||
*
|
||||
* Models will only be loaded if either a directory is supplied or it is in one of the modelPaths
|
||||
*
|
||||
* @var array Array of paths where models can be found
|
||||
*/
|
||||
private static $model_types = array();
|
||||
protected $modelPaths = array();
|
||||
|
||||
/**
|
||||
* Load a model.
|
||||
*
|
||||
* @param string $name Name of the model
|
||||
* @param string $directory Optional directory of the model
|
||||
*
|
||||
* @return object The Model object.
|
||||
*/
|
||||
public static function loadModel($name, $directory = null)
|
||||
public function __construct()
|
||||
{
|
||||
// Model load event
|
||||
$event = Events::fireEvent('modelLoadEvent', $name, $directory);
|
||||
$directory = ($event->directory === null ? Core::$appDir . DS . 'Models' : $event->directory);
|
||||
$name = ($event->model === null ? $name : $event->model);
|
||||
$this->modelPaths[] = Core::$appDir . DS . 'Models';
|
||||
}
|
||||
|
||||
$file = $directory.DS.'model.'.$name.'.php';
|
||||
if (isset(self::$model_types[$name])) {
|
||||
Logger::log('Loading Model: '.get_class(self::$model_types[$name]), get_class(self::$model_types[$name]));
|
||||
self::$models_array[$name] = self::$model_types[$name];
|
||||
} elseif (file_exists($file)) {
|
||||
include_once $file;
|
||||
$model = "\Application\Model\\".ucfirst($name);
|
||||
Logger::log('Loading Model: '.$model, $model);
|
||||
/**
|
||||
* Get a model.
|
||||
*
|
||||
* Supply the name and the model will be loaded from the supplied directory,
|
||||
* or from one of the modelPaths (which you can add).
|
||||
*
|
||||
* @param string $modelName Name of the model
|
||||
* @param string|null $directory Directory to load the model from, will ignore $modelPaths
|
||||
* @return ModelAbstract The Model object
|
||||
*/
|
||||
public function get($modelName, $directory = null)
|
||||
{
|
||||
if (empty($modelName))
|
||||
{
|
||||
throw new ModelException("Could not load model. No name provided", 1);
|
||||
}
|
||||
|
||||
return self::$models_array[$name] = new $model();
|
||||
} else {
|
||||
throw new ModelException("The requested model: \''.$name.'\' could not be found", 1);
|
||||
// First get the directories where the model can be located
|
||||
$directories = (is_null($directory) ? $this->modelPaths : array($directory));
|
||||
|
||||
// Fire a model load event
|
||||
$event = Events::fireEvent('modelLoadEvent', $modelName, $directories);
|
||||
$directories = $event->directories;
|
||||
$modelName = $event->modelName;
|
||||
|
||||
// If the event is cancelled, stop loading
|
||||
if ($event->isCancelled())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// And attempt to load the model
|
||||
return $this->loadModel($modelName, $directories);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load and return a model.
|
||||
*
|
||||
* Supply the name and the model will be loaded from one of the supplied directories
|
||||
*
|
||||
* @param string $modelName Name of the model
|
||||
* @param array $directories Directories to try and load the model from
|
||||
* @return ModelAbstract The Model object
|
||||
*/
|
||||
protected function loadModel($modelName, $directories)
|
||||
{
|
||||
if (empty($directories))
|
||||
{
|
||||
throw new ModelException("Could not load model. No directories provided", 1);
|
||||
}
|
||||
|
||||
// Now figure out the className and subdir
|
||||
$class = trim($modelName, '/');
|
||||
if (($last_slash = strrpos($class, '/')) !== FALSE)
|
||||
{
|
||||
// Extract the path
|
||||
$subdir = substr($class, 0, ++$last_slash);
|
||||
|
||||
// Get the filename from the path
|
||||
$class = substr($class, $last_slash);
|
||||
}
|
||||
else
|
||||
{
|
||||
$subdir = '';
|
||||
}
|
||||
|
||||
$class = ucfirst($class);
|
||||
|
||||
// Search for the model file
|
||||
foreach ($directories as $directory) {
|
||||
|
||||
// Determine the file
|
||||
$file = $directory . DS . $subdir . "model." . strtolower($class) . '.php';
|
||||
$className = '\Application\Model\\'.$class;
|
||||
|
||||
// If the class already exists, return a new instance directly
|
||||
if (class_exists($className, false))
|
||||
{
|
||||
return new $className();
|
||||
}
|
||||
|
||||
// If it doesn't, try and load the file
|
||||
if (file_exists($file))
|
||||
{
|
||||
include_once($file);
|
||||
return new $className();
|
||||
}
|
||||
}
|
||||
|
||||
// Maybe it's in a subdirectory with the same name as the class
|
||||
if ($subdir === '')
|
||||
{
|
||||
return $this->loadModel($class."/".$class, $directories);
|
||||
}
|
||||
|
||||
throw new ModelException("Could not load model. Model was not found", 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a path where models can be found
|
||||
*
|
||||
* @param string $directory The directory
|
||||
* @return void
|
||||
*/
|
||||
public function addModelPath($directory)
|
||||
{
|
||||
if (!in_array($directory, $this->ModelPaths))
|
||||
{
|
||||
$this->modelPaths[] = $directory;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a model.
|
||||
*
|
||||
* @param string $name Name of the model
|
||||
*
|
||||
* @return object The Model object
|
||||
*/
|
||||
public static function get($name)
|
||||
* Remove a path where models can be found
|
||||
*
|
||||
* @param string $directory The directory
|
||||
* @return void
|
||||
*/
|
||||
public function removeModelPath($directory)
|
||||
{
|
||||
// Get the name
|
||||
$name = strtolower($name);
|
||||
|
||||
// Check if it already exists
|
||||
if (isset(self::$models_array[$name])) {
|
||||
// Return if it does
|
||||
return self::$models_array[$name];
|
||||
} else {
|
||||
// If not, load and return afterwards
|
||||
return self::loadModel($name);
|
||||
if (($key = array_search($directory, $this->modelPaths)) !== false)
|
||||
{
|
||||
unset($this->modelPaths[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all current ModelPaths
|
||||
*
|
||||
* @return array Array of paths where models can be found
|
||||
*/
|
||||
public function getModelPaths()
|
||||
{
|
||||
return $this->modelPaths;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,173 @@
|
|||
<?php
|
||||
/**
|
||||
* FuzeWorks.
|
||||
*
|
||||
* The FuzeWorks MVC PHP FrameWork
|
||||
*
|
||||
* Copyright (C) 2015 TechFuze
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author TechFuze
|
||||
* @copyright Copyright (c) 2013 - 2016, Techfuze. (http://techfuze.net)
|
||||
* @copyright Copyright (c) 1996 - 2015, Free Software Foundation, Inc. (http://www.fsf.org/)
|
||||
* @license http://opensource.org/licenses/GPL-3.0 GPLv3 License
|
||||
*
|
||||
* @link http://fuzeworks.techfuze.net
|
||||
* @since Version 0.0.1
|
||||
*
|
||||
* @version Version 0.0.1
|
||||
*/
|
||||
|
||||
use FuzeWorks\Models;
|
||||
use FuzeWorks\Events;
|
||||
use FuzeWorks\EventPriority;
|
||||
|
||||
/**
|
||||
* Class ModelTest.
|
||||
*
|
||||
* Will test the FuzeWorks Model System.
|
||||
*/
|
||||
class modelTest extends CoreTestAbstract
|
||||
{
|
||||
protected $models;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->models = new Models();
|
||||
}
|
||||
|
||||
public function testGetModel()
|
||||
{
|
||||
$model = $this->models->get('TestGetModel', 'tests/models/testGetModel');
|
||||
$this->assertInstanceOf('\Application\Model\TestGetModel', $model);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testGetModel
|
||||
*/
|
||||
public function testReloadModel()
|
||||
{
|
||||
$model = $this->models->get('TestGetModel', 'tests/models/testGetModel');
|
||||
$this->assertInstanceOf('\Application\Model\TestGetModel', $model);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException FuzeWorks\Exception\ModelException
|
||||
*/
|
||||
public function testFailModelName()
|
||||
{
|
||||
$model = $this->models->get('');
|
||||
}
|
||||
|
||||
public function testEventLoadModelChange()
|
||||
{
|
||||
// Register the listener
|
||||
Events::addListener(array($this, 'listener_change'), 'modelLoadEvent', EventPriority::NORMAL);
|
||||
|
||||
// Load wrong model
|
||||
$model = $this->models->get('TestWrongModel', 'tests/models/testWrongDirectory');
|
||||
$this->assertInstanceOf('\Application\Model\TestRightModel', $model);
|
||||
}
|
||||
|
||||
// Change the directory and model name
|
||||
public function listener_change($event)
|
||||
{
|
||||
// First test input
|
||||
$this->assertEquals('TestWrongModel', $event->modelName);
|
||||
$this->assertContains('tests/models/testWrongDirectory', $event->directories);
|
||||
|
||||
// Then change variables
|
||||
$event->modelName = 'TestRightModel';
|
||||
$event->directories = array('tests/models/testRightDirectory');
|
||||
|
||||
// Return the event afterwards
|
||||
return $event;
|
||||
}
|
||||
|
||||
public function testEventLoadModelCancel()
|
||||
{
|
||||
// Register the listener
|
||||
Events::addListener(array($this, 'listener_cancel'), 'modelLoadEvent', EventPriority::NORMAL);
|
||||
|
||||
$this->assertFalse($this->models->get('TestModelCancel'));
|
||||
}
|
||||
|
||||
// Cancel the event
|
||||
public function listener_cancel($event)
|
||||
{
|
||||
$event->setCancelled(true);
|
||||
return $event;
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException FuzeWorks\Exception\ModelException
|
||||
*/
|
||||
public function testNoDirectories()
|
||||
{
|
||||
// Register the listener
|
||||
Events::addListener(array($this, 'listener_nodirectories'), 'modelLoadEvent', EventPriority::NORMAL);
|
||||
|
||||
$this->models->get('testNoDirectories');
|
||||
}
|
||||
|
||||
// Clean the directories array
|
||||
public function listener_nodirectories($event)
|
||||
{
|
||||
$event->directories = array();
|
||||
return $event;
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException FuzeWorks\Exception\ModelException
|
||||
*/
|
||||
public function testAddModelPathFail()
|
||||
{
|
||||
// First test if the model is not loaded yet
|
||||
$this->assertFalse(class_exists('TestAddModelPath', false));
|
||||
|
||||
// Now test if the model can be loaded (hint: it can not)
|
||||
$this->models->get('TestAddModelPathFail');
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testAddModelPathFail
|
||||
*/
|
||||
public function testAddModelPath()
|
||||
{
|
||||
// Add the modelPath
|
||||
$this->models->addModelPath('tests/models/testAddModelPath');
|
||||
|
||||
// And try to load it again
|
||||
$this->assertInstanceOf('Application\Model\TestAddModelPath', $this->models->get('TestAddModelPath'));
|
||||
}
|
||||
|
||||
public function testRemoveModelPath()
|
||||
{
|
||||
// Test if the path does NOT exist
|
||||
$this->assertFalse(in_array('tests/models/testRemoveModelPath', $this->models->getModelPaths()));
|
||||
|
||||
// Add it
|
||||
$this->models->addModelPath('tests/models/testRemoveModelPath');
|
||||
|
||||
// Assert if it's there
|
||||
$this->assertTrue(in_array('tests/models/testRemoveModelPath', $this->models->getModelPaths()));
|
||||
|
||||
// Remove it
|
||||
$this->models->removeModelPath('tests/models/testRemoveModelPath');
|
||||
|
||||
// And test if it's gone again
|
||||
$this->assertFalse(in_array('tests/models/testRemoveModelPath', $this->models->getModelPaths()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Application\Model;
|
||||
use FuzeWorks\ModelAbstract;
|
||||
|
||||
class TestAddModelPath extends ModelAbstract
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Application\Model;
|
||||
use FuzeWorks\ModelAbstract;
|
||||
|
||||
class TestGetModel extends ModelAbstract
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Application\Model;
|
||||
use FuzeWorks\ModelAbstract;
|
||||
|
||||
class TestRightModel extends ModelAbstract
|
||||
{
|
||||
|
||||
}
|
Loading…
Reference in New Issue