Code refactoring (add autoloader and change files organization)

This commit is contained in:
Frédéric Guillot 2014-05-22 12:28:28 -04:00
parent a750b8ab2a
commit 2230dd4e6b
105 changed files with 614 additions and 606 deletions

View File

@ -2,13 +2,15 @@
namespace Action;
use Core\Listener;
/**
* Base class for automatic actions
*
* @package action
* @author Frederic Guillot
*/
abstract class Base implements \Core\Listener
abstract class Base implements Listener
{
/**
* Project id

View File

@ -2,7 +2,7 @@
namespace Action;
require_once __DIR__.'/base.php';
use Model\Task;
/**
* Assign a color to a specific category
@ -27,7 +27,7 @@ class TaskAssignColorCategory extends Base
* @param integer $project_id Project id
* @param \Model\Task $task Task model instance
*/
public function __construct($project_id, \Model\Task $task)
public function __construct($project_id, Task $task)
{
parent::__construct($project_id);
$this->task = $task;

View File

@ -2,7 +2,7 @@
namespace Action;
require_once __DIR__.'/base.php';
use Model\Task;
/**
* Assign a color to a specific user
@ -27,7 +27,7 @@ class TaskAssignColorUser extends Base
* @param integer $project_id Project id
* @param \Model\Task $task Task model instance
*/
public function __construct($project_id, \Model\Task $task)
public function __construct($project_id, Task $task)
{
parent::__construct($project_id);
$this->task = $task;

View File

@ -2,7 +2,8 @@
namespace Action;
require_once __DIR__.'/base.php';
use Model\Task;
use Model\Acl;
/**
* Assign a task to the logged user
@ -36,7 +37,7 @@ class TaskAssignCurrentUser extends Base
* @param \Model\Task $task Task model instance
* @param \Model\Acl $acl Acl model instance
*/
public function __construct($project_id, \Model\Task $task, \Model\Acl $acl)
public function __construct($project_id, Task $task, Acl $acl)
{
parent::__construct($project_id);
$this->task = $task;

View File

@ -2,7 +2,7 @@
namespace Action;
require_once __DIR__.'/base.php';
use Model\Task;
/**
* Assign a task to a specific user
@ -27,7 +27,7 @@ class TaskAssignSpecificUser extends Base
* @param integer $project_id Project id
* @param \Model\Task $task Task model instance
*/
public function __construct($project_id, \Model\Task $task)
public function __construct($project_id, Task $task)
{
parent::__construct($project_id);
$this->task = $task;

View File

@ -2,7 +2,7 @@
namespace Action;
require_once __DIR__.'/base.php';
use Model\Task;
/**
* Close automatically a task
@ -27,7 +27,7 @@ class TaskClose extends Base
* @param integer $project_id Project id
* @param \Model\Task $task Task model instance
*/
public function __construct($project_id, \Model\Task $task)
public function __construct($project_id, Task $task)
{
parent::__construct($project_id);
$this->task = $task;

View File

@ -2,7 +2,7 @@
namespace Action;
require_once __DIR__.'/base.php';
use Model\Task;
/**
* Duplicate a task to another project
@ -27,7 +27,7 @@ class TaskDuplicateAnotherProject extends Base
* @param integer $project_id Project id
* @param \Model\Task $task Task model instance
*/
public function __construct($project_id, \Model\Task $task)
public function __construct($project_id, Task $task)
{
parent::__construct($project_id);
$this->task = $task;

View File

@ -2,8 +2,6 @@
namespace Controller;
require_once __DIR__.'/base.php';
/**
* Automatic actions management
*

View File

@ -2,7 +2,7 @@
namespace Controller;
require_once __DIR__.'/base.php';
use Model\Project;
/**
* Application controller
@ -19,7 +19,7 @@ class App extends Base
*/
public function index()
{
if ($this->project->countByStatus(\Model\Project::ACTIVE)) {
if ($this->project->countByStatus(Project::ACTIVE)) {
$this->response->redirect('?controller=board');
}
else {

View File

@ -2,6 +2,10 @@
namespace Controller;
use Core\Registry;
use Core\Translator;
use Model\LastLogin;
/**
* Base controller
*
@ -43,130 +47,35 @@ abstract class Base
public $session;
/**
* Acl model
* Registry instance
*
* @accesss protected
* @var \Model\Acl
* @access private
* @var Core\Registry
*/
protected $acl;
/**
* Action model
*
* @accesss protected
* @var \Model\Action
*/
protected $action;
/**
* Board model
*
* @accesss protected
* @var \Model\Board
*/
protected $board;
/**
* Config model
*
* @accesss protected
* @var \Model\Config
*/
protected $config;
/**
* Project model
*
* @accesss protected
* @var \Model\Project
*/
protected $project;
/**
* Task model
*
* @accesss protected
* @var \Model\Task
*/
protected $task;
/**
* User model
*
* @accesss protected
* @var \Model\User
*/
protected $user;
/**
* Comment model
*
* @accesss protected
* @var \Model\Comment
*/
protected $comment;
/**
* RememberMe model
*
* @accesss protected
* @var \Model\RememberMe
*/
protected $rememberMe;
/**
* LastLogin model
*
* @accesss protected
* @var \Model\LastLogin
*/
protected $lastLogin;
/**
* Google model
*
* @accesss protected
* @var \Model\Google
*/
protected $google;
/**
* Category model
*
* @accesss protected
* @var \Model\Category
*/
protected $category;
/**
* Event instance
*
* @accesss protected
* @var \Model\Event
*/
protected $event;
private $registry;
/**
* Constructor
*
* @access public
* @param \Core\Registry $registry
* @param \Core\Registry $registry Registry instance
*/
public function __construct(\Core\Registry $registry)
public function __construct(Registry $registry)
{
$this->acl = $registry->acl;
$this->action = $registry->action;
$this->board = $registry->board;
$this->config = $registry->config;
$this->project = $registry->project;
$this->task = $registry->task;
$this->user = $registry->user;
$this->comment = $registry->comment;
$this->rememberMe = $registry->rememberMe;
$this->lastLogin = $registry->lastLogin;
$this->google = $registry->google;
$this->category = $registry->category;
$this->event = $registry->shared('event');
$this->registry = $registry;
}
/**
* Load automatically models
*
* @access public
* @param string $name Model name
*/
public function __get($name)
{
$class = '\Model\\'.ucfirst($name);
$this->registry->$name = new $class($this->registry->shared('db'), $this->registry->shared('event'));
return $this->registry->shared($name);
}
/**
@ -188,7 +97,7 @@ abstract class Base
// Load translations
$language = $this->config->get('language', 'en_US');
if ($language !== 'en_US') \Translator\load($language);
if ($language !== 'en_US') Translator::load($language);
// Set timezone
date_default_timezone_set($this->config->get('timezone', 'UTC'));
@ -205,7 +114,7 @@ abstract class Base
else {
$this->lastLogin->create(
\Model\LastLogin::AUTH_REMEMBER_ME,
LastLogin::AUTH_REMEMBER_ME,
$this->acl->getUserId(),
$this->user->getIpAddress(),
$this->user->getUserAgent()
@ -226,6 +135,16 @@ abstract class Base
$this->project->attachEvents();
}
/**
* Application not found page (404 error)
*
* @access public
*/
public function notfound()
{
$this->response->html($this->template->layout('app_notfound', array('title' => t('Page not found'))));
}
/**
* Check if the current user have access to the given project
*
@ -253,16 +172,6 @@ abstract class Base
$this->response->redirect('?controller=project&action=create');
}
/**
* Application not found page (404 error)
*
* @access public
*/
public function notfound()
{
$this->response->html($this->template->layout('app_notfound', array('title' => t('Page not found'))));
}
/**
* Display the template show task (common between different actions)
*

View File

@ -2,7 +2,8 @@
namespace Controller;
require_once __DIR__.'/base.php';
use Model\Project;
use Model\User;
/**
* Board controller
@ -51,7 +52,7 @@ class Board extends Base
{
$task = $this->task->getById($this->request->getIntegerParam('task_id'));
$project = $this->project->getById($task['project_id']);
$projects = $this->project->getListByStatus(\Model\Project::ACTIVE);
$projects = $this->project->getListByStatus(Project::ACTIVE);
if ($this->acl->isRegularUser()) {
$projects = $this->project->filterListByAccess($projects, $this->acl->getUserId());
@ -142,7 +143,7 @@ class Board extends Base
*/
public function index()
{
$projects = $this->project->getListByStatus(\Model\Project::ACTIVE);
$projects = $this->project->getListByStatus(Project::ACTIVE);
if ($this->acl->isRegularUser()) {
$projects = $this->project->filterListByAccess($projects, $this->acl->getUserId());
@ -176,10 +177,10 @@ class Board extends Base
public function show()
{
$project_id = $this->request->getIntegerParam('project_id');
$user_id = $this->request->getIntegerParam('user_id', \Model\User::EVERYBODY_ID);
$user_id = $this->request->getIntegerParam('user_id', User::EVERYBODY_ID);
$this->checkProjectPermissions($project_id);
$projects = $this->project->getListByStatus(\Model\Project::ACTIVE);
$projects = $this->project->getListByStatus(Project::ACTIVE);
if ($this->acl->isRegularUser()) {
$projects = $this->project->filterListByAccess($projects, $this->acl->getUserId());

View File

@ -2,8 +2,6 @@
namespace Controller;
require_once __DIR__.'/base.php';
/**
* Categories management
*

View File

@ -2,8 +2,6 @@
namespace Controller;
require_once __DIR__.'/base.php';
/**
* Comment controller
*

View File

@ -2,8 +2,6 @@
namespace Controller;
require_once __DIR__.'/base.php';
/**
* Config controller
*

View File

@ -2,7 +2,7 @@
namespace Controller;
require_once __DIR__.'/base.php';
use Model\Task;
/**
* Project controller
@ -96,7 +96,7 @@ class Project extends Base
$filters = array(
array('column' => 'project_id', 'operator' => 'eq', 'value' => $project_id),
array('column' => 'is_active', 'operator' => 'eq', 'value' => \Model\Task::STATUS_CLOSED),
array('column' => 'is_active', 'operator' => 'eq', 'value' => Task::STATUS_CLOSED),
);
$tasks = $this->task->find($filters);

View File

@ -2,7 +2,7 @@
namespace Controller;
require_once __DIR__.'/base.php';
use Model\Project;
/**
* Task controller
@ -162,7 +162,7 @@ class Task extends Base
$this->response->html($this->template->layout('task_new', array(
'errors' => $errors,
'values' => $values,
'projects_list' => $this->project->getListByStatus(\Model\Project::ACTIVE),
'projects_list' => $this->project->getListByStatus(Project::ACTIVE),
'columns_list' => $this->board->getColumnsList($values['project_id']),
'users_list' => $this->project->getUsersList($values['project_id']),
'colors_list' => $this->task->getColors(),
@ -384,7 +384,7 @@ class Task extends Base
$this->response->html($this->template->layout('task_new', array(
'errors' => array(),
'values' => $task,
'projects_list' => $this->project->getListByStatus(\Model\Project::ACTIVE),
'projects_list' => $this->project->getListByStatus(Project::ACTIVE),
'columns_list' => $this->board->getColumnsList($task['project_id']),
'users_list' => $this->project->getUsersList($task['project_id']),
'colors_list' => $this->task->getColors(),

View File

@ -2,8 +2,6 @@
namespace Controller;
require_once __DIR__.'/base.php';
/**
* User controller
*

View File

@ -2,20 +2,6 @@
namespace Core;
/**
* Event listener interface
*
* @package core
* @author Frederic Guillot
*/
interface Listener {
/**
* @return boolean
*/
public function execute(array $data);
}
/**
* Event dispatcher class
*

17
app/Core/Listener.php Normal file
View File

@ -0,0 +1,17 @@
<?php
namespace Core;
/**
* Event listener interface
*
* @package core
* @author Frederic Guillot
*/
interface Listener {
/**
* @return boolean
*/
public function execute(array $data);
}

37
app/Core/Loader.php Normal file
View File

@ -0,0 +1,37 @@
<?php
namespace Core;
/**
* Loader class
*
* @package core
* @author Frederic Guillot
*/
class Loader
{
/**
* Load the missing class
*
* @access public
* @param string $class Class name
*/
public function load($class)
{
$filename = __DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php';
if (file_exists($filename)) {
require $filename;
}
}
/**
* Register the autoloader
*
* @access public
*/
public function execute()
{
spl_autoload_register(array($this, 'load'));
}
}

View File

@ -2,17 +2,46 @@
namespace Core;
require __DIR__.'/request.php';
require __DIR__.'/response.php';
require __DIR__.'/session.php';
require __DIR__.'/template.php';
/**
* Router class
*
* @package core
* @author Frederic Guillot
*/
class Router
{
/**
* Controller name
*
* @access private
* @var string
*/
private $controller = '';
/**
* Action name
*
* @access private
* @var string
*/
private $action = '';
/**
* Registry instance
*
* @access private
* @var Core\Registry
*/
private $registry;
/**
* Constructor
*
* @access public
* @param Core\Registry $registry Registry instance
* @param string $controller Controller name
* @param string $action Action name
*/
public function __construct(Registry $registry, $controller = '', $action = '')
{
$this->registry = $registry;
@ -21,7 +50,11 @@ class Router
}
/**
* @param string $default_value
* Check controller and action parameter
*
* @access public
* @param string $value Controller or action name
* @param string $default_value Default value if validation fail
*/
public function sanitize($value, $default_value)
{
@ -29,8 +62,12 @@ class Router
}
/**
* @param string $filename
* @param string $class
* Load a controller and execute the action
*
* @access public
* @param string $filename Controller filename
* @param string $class Class name
* @param string $method Method name
*/
public function load($filename, $class, $method)
{
@ -38,7 +75,9 @@ class Router
require $filename;
if (! method_exists($class, $method)) return false;
if (! method_exists($class, $method)) {
return false;
}
$instance = new $class($this->registry);
$instance->request = new Request;
@ -54,12 +93,18 @@ class Router
return false;
}
/**
* Find a route
*
* @access public
*/
public function execute()
{
$this->controller = $this->sanitize($this->controller, 'app');
$this->action = $this->sanitize($this->action, 'index');
$filename = __DIR__.'/../Controller/'.ucfirst($this->controller).'.php';
if (! $this->load('controllers/'.$this->controller.'.php', '\Controller\\'.$this->controller, $this->action)) {
if (! $this->load($filename, '\Controller\\'.$this->controller, $this->action)) {
die('Page not found!');
}
}

72
app/Core/Template.php Normal file
View File

@ -0,0 +1,72 @@
<?php
namespace Core;
/**
* Template class
*
* @package core
* @author Frederic Guillot
*/
class Template
{
/**
* Template path
*
* @var string
*/
const PATH = 'app/Templates/';
/**
* Load a template
*
* Example:
*
* $template->load('template_name', ['bla' => 'value']);
*
* @access public
* @return string
*/
public function load()
{
if (func_num_args() < 1 || func_num_args() > 2) {
die('Invalid template arguments');
}
if (! file_exists(self::PATH.func_get_arg(0).'.php')) {
die('Unable to load the template: "'.func_get_arg(0).'"');
}
if (func_num_args() === 2) {
if (! is_array(func_get_arg(1))) {
die('Template variables must be an array');
}
extract(func_get_arg(1));
}
ob_start();
include self::PATH.func_get_arg(0).'.php';
return ob_get_clean();
}
/**
* Render a page layout
*
* @access public
* @param string $template_name Template name
* @param array $template_args Key/value map
* @param string $layout_name Layout name
* @return string
*/
public function layout($template_name, array $template_args = array(), $layout_name = 'layout')
{
return $this->load(
$layout_name,
$template_args + array('content_for_layout' => $this->load($template_name, $template_args))
);
}
}

155
app/Core/Translator.php Normal file
View File

@ -0,0 +1,155 @@
<?php
namespace Core;
/**
* Translator class
*
* @package core
* @author Frederic Guillot
*/
class Translator
{
/**
* Locales path
*
* @var string
*/
const PATH = 'app/Locales/';
/**
* Locales
*
* @static
* @access private
* @var array
*/
private static $locales = array();
/**
* Get a translation
*
* $translator->translate('I have %d kids', 5);
*
* @access public
* @return string
*/
public function translate($identifier)
{
$args = func_get_args();
array_shift($args);
array_unshift($args, $this->get($identifier, $identifier));
foreach ($args as &$arg) {
$arg = htmlspecialchars($arg, ENT_QUOTES, 'UTF-8', false);
}
return call_user_func_array(
'sprintf',
$args
);
}
/**
* Get a formatted number
*
* $translator->number(1234.56);
*
* @access public
* @param float $number Number to format
* @return string
*/
public function number($number)
{
return number_format(
$number,
$this->get('number.decimals', 2),
$this->get('number.decimals_separator', '.'),
$this->get('number.thousands_separator', ',')
);
}
/**
* Get a formatted currency number
*
* $translator->currency(1234.56);
*
* @access public
* @param float $amount Number to format
* @return string
*/
public function currency($amount)
{
$position = $this->get('currency.position', 'before');
$symbol = $this->get('currency.symbol', '$');
$str = '';
if ($position === 'before') {
$str .= $symbol;
}
$str .= $this->number($amount);
if ($position === 'after') {
$str .= ' '.$symbol;
}
return $str;
}
/**
* Get a formatted datetime
*
* $translator->datetime('%Y-%m-%d', time());
*
* @access public
* @param string $format Format defined by the strftime function
* @param integer $timestamp Unix timestamp
* @return string
*/
public function datetime($format, $timestamp)
{
if (! $timestamp) {
return '';
}
return strftime($this->get($format, $format), (int) $timestamp);
}
/**
* Get an identifier from the translations or return the default
*
* @access public
* @param string $idendifier Locale identifier
* @param string $default Default value
* @return string
*/
public function get($identifier, $default = '')
{
if (isset(self::$locales[$identifier])) {
return self::$locales[$identifier];
}
else {
return $default;
}
}
/**
* Load translations
*
* @static
* @access public
* @param string $language Locale code: fr_FR
*/
public static function load($language)
{
setlocale(LC_TIME, $language.'.UTF-8', $language);
$filename = self::PATH.$language.DIRECTORY_SEPARATOR.'translations.php';
if (file_exists($filename)) {
self::$locales = require $filename;
}
}
}

View File

@ -2,8 +2,8 @@
namespace Event;
use \Core\Listener;
use \Model\Project;
use Core\Listener;
use Model\Project;
/**
* Task modification listener

View File

@ -330,4 +330,5 @@ return array(
// 'Filter by category' => '',
// 'All categories' => '',
// 'No category' => '',
// 'The name is required' => '',
);

View File

@ -330,4 +330,5 @@ return array(
'Filter by category' => 'Filtrer par catégorie',
'All categories' => 'Toutes les catégories',
'No category' => 'Aucune catégorie',
'The name is required' => 'Le nom est requis',
);

View File

@ -335,4 +335,5 @@ return array(
// 'Filter by category' => '',
// 'All categories' => '',
// 'No category' => '',
// 'The name is required' => '',
);

View File

@ -331,4 +331,5 @@ return array(
// 'Filter by category' => '',
// 'All categories' => '',
// 'No category' => '',
// 'The name is required' => '',
);

View File

@ -2,8 +2,6 @@
namespace Model;
require_once __DIR__.'/base.php';
/**
* Acl model
*

View File

@ -2,11 +2,9 @@
namespace Model;
require_once __DIR__.'/base.php';
require_once __DIR__.'/task.php';
use \SimpleValidator\Validator;
use \SimpleValidator\Validators;
use LogicException;
use SimpleValidator\Validator;
use SimpleValidator\Validators;
/**
* Action model
@ -222,31 +220,25 @@ class Action extends Base
{
switch ($name) {
case 'TaskClose':
require_once __DIR__.'/../actions/task_close.php';
$className = '\Action\TaskClose';
return new $className($project_id, new Task($this->db, $this->event));
case 'TaskAssignCurrentUser':
require_once __DIR__.'/../actions/task_assign_current_user.php';
$className = '\Action\TaskAssignCurrentUser';
return new $className($project_id, new Task($this->db, $this->event), new Acl($this->db, $this->event));
case 'TaskAssignSpecificUser':
require_once __DIR__.'/../actions/task_assign_specific_user.php';
$className = '\Action\TaskAssignSpecificUser';
return new $className($project_id, new Task($this->db, $this->event));
case 'TaskDuplicateAnotherProject':
require_once __DIR__.'/../actions/task_duplicate_another_project.php';
$className = '\Action\TaskDuplicateAnotherProject';
return new $className($project_id, new Task($this->db, $this->event));
case 'TaskAssignColorUser':
require_once __DIR__.'/../actions/task_assign_color_user.php';
$className = '\Action\TaskAssignColorUser';
return new $className($project_id, new Task($this->db, $this->event));
case 'TaskAssignColorCategory':
require_once __DIR__.'/../actions/task_assign_color_category.php';
$className = '\Action\TaskAssignColorCategory';
return new $className($project_id, new Task($this->db, $this->event));
default:
throw new \LogicException('Action not found: '.$name);
throw new LogicException('Action not found: '.$name);
}
}

View File

@ -2,18 +2,21 @@
namespace Model;
require __DIR__.'/../vendor/SimpleValidator/Validator.php';
require __DIR__.'/../vendor/SimpleValidator/Base.php';
require __DIR__.'/../vendor/SimpleValidator/Validators/Required.php';
require __DIR__.'/../vendor/SimpleValidator/Validators/Unique.php';
require __DIR__.'/../vendor/SimpleValidator/Validators/MaxLength.php';
require __DIR__.'/../vendor/SimpleValidator/Validators/MinLength.php';
require __DIR__.'/../vendor/SimpleValidator/Validators/Integer.php';
require __DIR__.'/../vendor/SimpleValidator/Validators/Equals.php';
require __DIR__.'/../vendor/SimpleValidator/Validators/AlphaNumeric.php';
require __DIR__.'/../vendor/SimpleValidator/Validators/GreaterThan.php';
require __DIR__.'/../vendor/SimpleValidator/Validators/Date.php';
require __DIR__.'/../vendor/SimpleValidator/Validators/Email.php';
require __DIR__.'/../../vendor/SimpleValidator/Validator.php';
require __DIR__.'/../../vendor/SimpleValidator/Base.php';
require __DIR__.'/../../vendor/SimpleValidator/Validators/Required.php';
require __DIR__.'/../../vendor/SimpleValidator/Validators/Unique.php';
require __DIR__.'/../../vendor/SimpleValidator/Validators/MaxLength.php';
require __DIR__.'/../../vendor/SimpleValidator/Validators/MinLength.php';
require __DIR__.'/../../vendor/SimpleValidator/Validators/Integer.php';
require __DIR__.'/../../vendor/SimpleValidator/Validators/Equals.php';
require __DIR__.'/../../vendor/SimpleValidator/Validators/AlphaNumeric.php';
require __DIR__.'/../../vendor/SimpleValidator/Validators/GreaterThan.php';
require __DIR__.'/../../vendor/SimpleValidator/Validators/Date.php';
require __DIR__.'/../../vendor/SimpleValidator/Validators/Email.php';
use Core\Event;
use PicoDb\Database;
/**
* Base model class
@ -43,10 +46,10 @@ abstract class Base
* Constructor
*
* @access public
* @param PicoDb\Database $db Database instance
* @param \PicoDb\Database $db Database instance
* @param \Core\Event $event Event dispatcher instance
*/
public function __construct(\PicoDb\Database $db, \Core\Event $event)
public function __construct(Database $db, Event $event)
{
$this->db = $db;
$this->event = $event;

View File

@ -2,11 +2,8 @@
namespace Model;
require_once __DIR__.'/base.php';
require_once __DIR__.'/task.php';
use \SimpleValidator\Validator;
use \SimpleValidator\Validators;
use SimpleValidator\Validator;
use SimpleValidator\Validators;
/**
* Board model

View File

@ -2,8 +2,6 @@
namespace Model;
require_once __DIR__.'/base.php';
use SimpleValidator\Validator;
use SimpleValidator\Validators;

View File

@ -2,10 +2,8 @@
namespace Model;
require_once __DIR__.'/base.php';
use \SimpleValidator\Validator;
use \SimpleValidator\Validators;
use SimpleValidator\Validator;
use SimpleValidator\Validators;
/**
* Comment model

View File

@ -2,10 +2,8 @@
namespace Model;
require_once __DIR__.'/base.php';
use \SimpleValidator\Validator;
use \SimpleValidator\Validators;
use SimpleValidator\Validator;
use SimpleValidator\Validators;
/**
* Config model

View File

@ -2,14 +2,13 @@
namespace Model;
require_once __DIR__.'/base.php';
require __DIR__.'/../vendor/OAuth/bootstrap.php';
require __DIR__.'/../../vendor/OAuth/bootstrap.php';
use \OAuth\Common\Storage\Session;
use \OAuth\Common\Consumer\Credentials;
use \OAuth\Common\Http\Uri\UriFactory;
use \OAuth\ServiceFactory;
use \OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Storage\Session;
use OAuth\Common\Consumer\Credentials;
use OAuth\Common\Http\Uri\UriFactory;
use OAuth\ServiceFactory;
use OAuth\Common\Http\Exception\TokenResponseException;
/**
* Google model

View File

@ -2,8 +2,6 @@
namespace Model;
require_once __DIR__.'/base.php';
/**
* LastLogin model
*

View File

@ -2,8 +2,6 @@
namespace Model;
require_once __DIR__.'/base.php';
/**
* LDAP model
*

View File

@ -2,12 +2,6 @@
namespace Model;
require_once __DIR__.'/base.php';
require_once __DIR__.'/acl.php';
require_once __DIR__.'/board.php';
require_once __DIR__.'/task.php';
require_once __DIR__.'/../events/task_modification.php';
use SimpleValidator\Validator;
use SimpleValidator\Validators;
use Event\TaskModification;

View File

@ -2,8 +2,6 @@
namespace Model;
require_once __DIR__.'/base.php';
/**
* RememberMe model
*

View File

@ -2,8 +2,6 @@
namespace Model;
require_once __DIR__.'/base.php';
use SimpleValidator\Validator;
use SimpleValidator\Validators;
use DateTime;

View File

@ -2,10 +2,8 @@
namespace Model;
require_once __DIR__.'/base.php';
use \SimpleValidator\Validator;
use \SimpleValidator\Validators;
use SimpleValidator\Validator;
use SimpleValidator\Validators;
/**
* User model

View File

@ -2,6 +2,8 @@
namespace Schema;
const VERSION = 16;
function version_16($pdo)
{
$pdo->exec("

View File

@ -2,6 +2,8 @@
namespace Schema;
const VERSION = 16;
function version_16($pdo)
{
$pdo->exec("

View File

@ -36,5 +36,5 @@ if (! is_writable('data')) {
// Include password_compat for PHP < 5.5
if (version_compare(PHP_VERSION, '5.5.0', '<')) {
require __DIR__.'/vendor/password.php';
require __DIR__.'/../vendor/password.php';
}

98
app/common.php Normal file
View File

@ -0,0 +1,98 @@
<?php
require __DIR__.'/Core/Loader.php';
require __DIR__.'/helpers.php';
require __DIR__.'/translator.php';
use Core\Event;
use Core\Loader;
use Core\Registry;
// Include custom config file
if (file_exists('config.php')) {
require 'config.php';
}
// Board refresh frequency in seconds for the public board view
defined('BOARD_PUBLIC_CHECK_INTERVAL') or define('BOARD_PUBLIC_CHECK_INTERVAL', 60);
// Board refresh frequency in seconds (the value 0 disable this feature)
defined('BOARD_CHECK_INTERVAL') or define('BOARD_CHECK_INTERVAL', 10);
// Custom session save path
defined('SESSION_SAVE_PATH') or define('SESSION_SAVE_PATH', '');
// Application version
defined('APP_VERSION') or define('APP_VERSION', 'master');
// Base directory
define('BASE_URL_DIRECTORY', dirname($_SERVER['PHP_SELF']));
// Database driver: sqlite or mysql
defined('DB_DRIVER') or define('DB_DRIVER', 'sqlite');
// Sqlite configuration
defined('DB_FILENAME') or define('DB_FILENAME', 'data/db.sqlite');
// Mysql configuration
defined('DB_USERNAME') or define('DB_USERNAME', 'root');
defined('DB_PASSWORD') or define('DB_PASSWORD', '');
defined('DB_HOSTNAME') or define('DB_HOSTNAME', 'localhost');
defined('DB_NAME') or define('DB_NAME', 'kanboard');
// LDAP configuration
defined('LDAP_AUTH') or define('LDAP_AUTH', false);
defined('LDAP_SERVER') or define('LDAP_SERVER', '');
defined('LDAP_PORT') or define('LDAP_PORT', 389);
defined('LDAP_USER_DN') or define('LDAP_USER_DN', '%s');
// Google authentication
defined('GOOGLE_AUTH') or define('GOOGLE_AUTH', false);
defined('GOOGLE_CLIENT_ID') or define('GOOGLE_CLIENT_ID', '');
defined('GOOGLE_CLIENT_SECRET') or define('GOOGLE_CLIENT_SECRET', '');
$loader = new Loader;
$loader->execute();
$registry = new Registry;
$registry->db = function() use ($registry) {
require __DIR__.'/../vendor/PicoDb/Database.php';
if (DB_DRIVER === 'sqlite') {
require __DIR__.'/Schema/Sqlite.php';
$db = new \PicoDb\Database(array(
'driver' => 'sqlite',
'filename' => DB_FILENAME
));
}
elseif (DB_DRIVER === 'mysql') {
require __DIR__.'/Schema/Mysql.php';
$db = new \PicoDb\Database(array(
'driver' => 'mysql',
'hostname' => DB_HOSTNAME,
'username' => DB_USERNAME,
'password' => DB_PASSWORD,
'database' => DB_NAME,
'charset' => 'utf8',
));
}
else {
die('Database driver not supported');
}
if ($db->schema()->check(Schema\VERSION)) {
return $db;
}
else {
die('Unable to migrate database schema!');
}
};
$registry->event = function() use ($registry) {
return new Event;
};

36
app/translator.php Normal file
View File

@ -0,0 +1,36 @@
<?php
use Core\Translator;
// Get a translation
function t()
{
$t = new Translator;
return call_user_func_array(array($t, 'translate'), func_get_args());
}
// Get a locale currency
function c($value)
{
$t = new Translator;
return $t->currency($value);
}
// Get a formatted number
function n($value)
{
$t = new Translator;
return $t->number($value);
}
// Get a locale date
function dt($format, $timestamp)
{
$t = new Translator;
return $t->datetime($format, $timestamp);
}
// Plurals, return $t2 if $value > 1
function p($value, $t1, $t2) {
return $value > 1 ? $t2 : $t1;
}

View File

@ -45,6 +45,7 @@
// Stop events
function board_unload_events()
{
$("[data-task-id]").off();
clearInterval(checkInterval);
}

View File

@ -1,156 +0,0 @@
<?php
require __DIR__.'/core/registry.php';
require __DIR__.'/core/helper.php';
require __DIR__.'/core/translator.php';
$registry = new Core\Registry;
$registry->db_version = 16;
$registry->db = function() use ($registry) {
require __DIR__.'/vendor/PicoDb/Database.php';
if (DB_DRIVER === 'sqlite') {
require __DIR__.'/schemas/sqlite.php';
$db = new \PicoDb\Database(array(
'driver' => 'sqlite',
'filename' => DB_FILENAME
));
}
elseif (DB_DRIVER === 'mysql') {
require __DIR__.'/schemas/mysql.php';
$db = new \PicoDb\Database(array(
'driver' => 'mysql',
'hostname' => DB_HOSTNAME,
'username' => DB_USERNAME,
'password' => DB_PASSWORD,
'database' => DB_NAME,
'charset' => 'utf8',
));
}
else {
die('Database driver not supported');
}
if ($db->schema()->check($registry->db_version)) {
return $db;
}
else {
die('Unable to migrate database schema!');
}
};
$registry->event = function() use ($registry) {
require __DIR__.'/core/event.php';
return new \Core\Event;
};
$registry->action = function() use ($registry) {
require_once __DIR__.'/models/action.php';
return new \Model\Action($registry->shared('db'), $registry->shared('event'));
};
$registry->config = function() use ($registry) {
require_once __DIR__.'/models/config.php';
return new \Model\Config($registry->shared('db'), $registry->shared('event'));
};
$registry->acl = function() use ($registry) {
require_once __DIR__.'/models/acl.php';
return new \Model\Acl($registry->shared('db'), $registry->shared('event'));
};
$registry->user = function() use ($registry) {
require_once __DIR__.'/models/user.php';
return new \Model\User($registry->shared('db'), $registry->shared('event'));
};
$registry->comment = function() use ($registry) {
require_once __DIR__.'/models/comment.php';
return new \Model\Comment($registry->shared('db'), $registry->shared('event'));
};
$registry->task = function() use ($registry) {
require_once __DIR__.'/models/task.php';
return new \Model\Task($registry->shared('db'), $registry->shared('event'));
};
$registry->board = function() use ($registry) {
require_once __DIR__.'/models/board.php';
return new \Model\Board($registry->shared('db'), $registry->shared('event'));
};
$registry->project = function() use ($registry) {
require_once __DIR__.'/models/project.php';
return new \Model\Project($registry->shared('db'), $registry->shared('event'));
};
$registry->action = function() use ($registry) {
require_once __DIR__.'/models/action.php';
return new \Model\Action($registry->shared('db'), $registry->shared('event'));
};
$registry->rememberMe = function() use ($registry) {
require_once __DIR__.'/models/remember_me.php';
return new \Model\RememberMe($registry->shared('db'), $registry->shared('event'));
};
$registry->lastLogin = function() use ($registry) {
require_once __DIR__.'/models/last_login.php';
return new \Model\LastLogin($registry->shared('db'), $registry->shared('event'));
};
$registry->google = function() use ($registry) {
require_once __DIR__.'/models/google.php';
return new \Model\Google($registry->shared('db'), $registry->shared('event'));
};
$registry->category = function() use ($registry) {
require_once __DIR__.'/models/category.php';
return new \Model\Category($registry->shared('db'), $registry->shared('event'));
};
if (file_exists('config.php')) require 'config.php';
// Board refresh frequency in seconds for the public board view
defined('BOARD_PUBLIC_CHECK_INTERVAL') or define('BOARD_PUBLIC_CHECK_INTERVAL', 60);
// Board refresh frequency in seconds (the value 0 disable this feature)
defined('BOARD_CHECK_INTERVAL') or define('BOARD_CHECK_INTERVAL', 10);
// Custom session save path
defined('SESSION_SAVE_PATH') or define('SESSION_SAVE_PATH', '');
// Application version
defined('APP_VERSION') or define('APP_VERSION', 'master');
// Base directory
define('BASE_URL_DIRECTORY', dirname($_SERVER['PHP_SELF']));
// Database driver: sqlite or mysql
defined('DB_DRIVER') or define('DB_DRIVER', 'sqlite');
// Sqlite configuration
defined('DB_FILENAME') or define('DB_FILENAME', 'data/db.sqlite');
// Mysql configuration
defined('DB_USERNAME') or define('DB_USERNAME', 'root');
defined('DB_PASSWORD') or define('DB_PASSWORD', '');
defined('DB_HOSTNAME') or define('DB_HOSTNAME', 'localhost');
defined('DB_NAME') or define('DB_NAME', 'kanboard');
// LDAP configuration
defined('LDAP_AUTH') or define('LDAP_AUTH', false);
defined('LDAP_SERVER') or define('LDAP_SERVER', '');
defined('LDAP_PORT') or define('LDAP_PORT', 389);
defined('LDAP_USER_DN') or define('LDAP_USER_DN', '%s');
// Google authentication
defined('GOOGLE_AUTH') or define('GOOGLE_AUTH', false);
defined('GOOGLE_CLIENT_ID') or define('GOOGLE_CLIENT_ID', '');
defined('GOOGLE_CLIENT_SECRET') or define('GOOGLE_CLIENT_SECRET', '');

View File

@ -1,7 +1,10 @@
<?php
// Auto-refresh frequency in seconds for the public board view (60 seconds by default)
define('AUTO_REFRESH_DURATION', 60);
define('BOARD_PUBLIC_CHECK_INTERVAL', 60);
// Board refresh frequency in seconds (the value 0 disable this feature, 10 seconds by default)
define('BOARD_CHECK_INTERVAL', 10);
// Database driver: sqlite or mysql (sqlite by default)
define('DB_DRIVER', 'sqlite');

View File

@ -1,40 +0,0 @@
<?php
namespace Core;
class Template
{
const PATH = 'templates/';
// Template\load('template_name', ['bla' => 'value']);
public function load()
{
if (func_num_args() < 1 || func_num_args() > 2) {
die('Invalid template arguments');
}
if (! file_exists(self::PATH.func_get_arg(0).'.php')) {
die('Unable to load the template: "'.func_get_arg(0).'"');
}
if (func_num_args() === 2) {
if (! is_array(func_get_arg(1))) {
die('Template variables must be an array');
}
extract(func_get_arg(1));
}
ob_start();
include self::PATH.func_get_arg(0).'.php';
return ob_get_clean();
}
public function layout($template_name, array $template_args = array(), $layout_name = 'layout')
{
return $this->load($layout_name, $template_args + array('content_for_layout' => $this->load($template_name, $template_args)));
}
}

View File

@ -1,130 +0,0 @@
<?php
namespace Translator {
const PATH = 'locales/';
function translate($identifier)
{
$args = \func_get_args();
\array_shift($args);
\array_unshift($args, get($identifier, $identifier));
foreach ($args as &$arg) {
$arg = htmlspecialchars($arg, ENT_QUOTES, 'UTF-8', false);
}
return \call_user_func_array(
'sprintf',
$args
);
}
function number($number)
{
return number_format(
$number,
get('number.decimals', 2),
get('number.decimals_separator', '.'),
get('number.thousands_separator', ',')
);
}
function currency($amount)
{
$position = get('currency.position', 'before');
$symbol = get('currency.symbol', '$');
$str = '';
if ($position === 'before') {
$str .= $symbol;
}
$str .= number($amount);
if ($position === 'after') {
$str .= ' '.$symbol;
}
return $str;
}
function datetime($format, $timestamp)
{
if (! $timestamp) {
return '';
}
return strftime(get($format, $format), (int) $timestamp);
}
function get($identifier, $default = '')
{
$locales = container();
if (isset($locales[$identifier])) {
return $locales[$identifier];
}
else {
return $default;
}
}
function load($language)
{
setlocale(LC_TIME, $language.'.UTF-8', $language);
$path = PATH.$language;
$locales = array();
if (is_dir($path)) {
$dir = new \DirectoryIterator($path);
foreach ($dir as $fileinfo) {
if (strpos($fileinfo->getFilename(), '.php') !== false) {
$locales = array_merge($locales, include $fileinfo->getPathname());
}
}
}
container($locales);
}
function container($locales = null)
{
static $values = array();
if ($locales !== null) {
$values = $locales;
}
return $values;
}
}
namespace {
function t() {
return call_user_func_array('\Translator\translate', func_get_args());
}
function c() {
return call_user_func_array('\Translator\currency', func_get_args());
}
function n() {
return call_user_func_array('\Translator\number', func_get_args());
}
function dt() {
return call_user_func_array('\Translator\datetime', func_get_args());
}
function p($value, $t1, $t2) {
return $value > 1 ? $t2 : $t1;
}
}

View File

@ -1,8 +1,9 @@
<?php
require __DIR__.'/check_setup.php';
require __DIR__.'/common.php';
require __DIR__.'/core/router.php';
require __DIR__.'/app/check_setup.php';
require __DIR__.'/app/common.php';
$router = new Core\Router($registry);
use Core\Router;
$router = new Router($registry);
$router->execute();

Some files were not shown because too many files have changed in this diff Show More