diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/Core/Loader.php | 33 | ||||
-rw-r--r-- | app/Model/Project.php | 31 | ||||
-rw-r--r-- | app/Model/Task.php | 38 | ||||
-rw-r--r-- | app/check_setup.php | 5 | ||||
-rw-r--r-- | app/common.php | 179 | ||||
-rw-r--r-- | app/constants.php | 70 | ||||
-rw-r--r-- | app/functions.php | 131 | ||||
-rw-r--r-- | app/translator.php | 43 |
8 files changed, 301 insertions, 229 deletions
diff --git a/app/Core/Loader.php b/app/Core/Loader.php index 7c437654..151081c1 100644 --- a/app/Core/Loader.php +++ b/app/Core/Loader.php @@ -11,17 +11,29 @@ namespace Core; class Loader { /** + * List of paths + * + * @access private + * @var array + */ + private $paths = array(); + + /** * Load the missing class * * @access public - * @param string $class Class name + * @param string $class Class name with namespace */ public function load($class) { - $filename = __DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php'; + foreach ($this->paths as $path) { + + $filename = $path.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php'; - if (file_exists($filename)) { - require $filename; + if (file_exists($filename)) { + require $filename; + break; + } } } @@ -34,4 +46,17 @@ class Loader { spl_autoload_register(array($this, 'load')); } + + /** + * Register a new path + * + * @access public + * @param string $path Path + * @return Core\Loader + */ + public function setPath($path) + { + $this->paths[] = $path; + return $this; + } } diff --git a/app/Model/Project.php b/app/Model/Project.php index 0ba18498..f8df1ae1 100644 --- a/app/Model/Project.php +++ b/app/Model/Project.php @@ -553,7 +553,8 @@ class Project extends Base */ public function update(array $values) { - return $this->db->table(self::TABLE)->eq('id', $values['id'])->save($values); + return $this->exists($values['id']) && + $this->db->table(self::TABLE)->eq('id', $values['id'])->save($values); } /** @@ -569,6 +570,18 @@ class Project extends Base } /** + * Return true if the project exists + * + * @access public + * @param integer $project_id Project id + * @return boolean + */ + public function exists($project_id) + { + return $this->db->table(self::TABLE)->eq('id', $project_id)->count() === 1; + } + + /** * Enable a project * * @access public @@ -577,10 +590,11 @@ class Project extends Base */ public function enable($project_id) { - return $this->db + return $this->exists($project_id) && + $this->db ->table(self::TABLE) ->eq('id', $project_id) - ->save(array('is_active' => 1)); + ->update(array('is_active' => 1)); } /** @@ -592,10 +606,11 @@ class Project extends Base */ public function disable($project_id) { - return $this->db + return $this->exists($project_id) && + $this->db ->table(self::TABLE) ->eq('id', $project_id) - ->save(array('is_active' => 0)); + ->update(array('is_active' => 0)); } /** @@ -607,7 +622,8 @@ class Project extends Base */ public function enablePublicAccess($project_id) { - return $this->db + return $this->exists($project_id) && + $this->db ->table(self::TABLE) ->eq('id', $project_id) ->save(array('is_public' => 1, 'token' => Security::generateToken())); @@ -622,7 +638,8 @@ class Project extends Base */ public function disablePublicAccess($project_id) { - return $this->db + return $this->exists($project_id) && + $this->db ->table(self::TABLE) ->eq('id', $project_id) ->save(array('is_public' => 0, 'token' => '')); diff --git a/app/Model/Task.php b/app/Model/Task.php index 6f62c3d2..fcee67f7 100644 --- a/app/Model/Task.php +++ b/app/Model/Task.php @@ -150,16 +150,16 @@ class Task extends Base * Count all tasks for a given project and status * * @access public - * @param integer $project_id Project id - * @param array $status List of status id + * @param integer $project_id Project id + * @param integer $status_id Status id * @return array */ - public function getAll($project_id, array $status = array(self::STATUS_OPEN, self::STATUS_CLOSED)) + public function getAll($project_id, $status_id = self::STATUS_OPEN) { return $this->db ->table(self::TABLE) ->eq('project_id', $project_id) - ->in('is_active', $status) + ->eq('is_active', $status_id) ->findAll(); } @@ -382,6 +382,10 @@ class Task extends Base if (isset($values['score']) && empty($values['score'])) { $values['score'] = 0; } + + if (isset($values['is_active'])) { + $values['is_active'] = (int) $values['is_active']; + } } /** @@ -488,6 +492,18 @@ class Task extends Base } /** + * Return true if the project exists + * + * @access public + * @param integer $task_id Task id + * @return boolean + */ + public function exists($task_id) + { + return $this->db->table(self::TABLE)->eq('id', $task_id)->count() === 1; + } + + /** * Mark a task closed * * @access public @@ -496,6 +512,10 @@ class Task extends Base */ public function close($task_id) { + if (! $this->exists($task_id)) { + return false; + } + $result = $this->db ->table(self::TABLE) ->eq('id', $task_id) @@ -520,12 +540,16 @@ class Task extends Base */ public function open($task_id) { + if (! $this->exists($task_id)) { + return false; + } + $result = $this->db ->table(self::TABLE) ->eq('id', $task_id) ->update(array( 'is_active' => 1, - 'date_completed' => '' + 'date_completed' => 0 )); if ($result) { @@ -544,6 +568,10 @@ class Task extends Base */ public function remove($task_id) { + if (! $this->exists($task_id)) { + return false; + } + $this->file->removeAll($task_id); return $this->db->table(self::TABLE)->eq('id', $task_id)->remove(); diff --git a/app/check_setup.php b/app/check_setup.php index 9ed16967..c4359d7a 100644 --- a/app/check_setup.php +++ b/app/check_setup.php @@ -33,8 +33,3 @@ if (! extension_loaded('mbstring')) { if (! is_writable('data')) { die('The directory "data" must be writeable by your web server user'); } - -// Include password_compat for PHP < 5.5 -if (version_compare(PHP_VERSION, '5.5.0', '<')) { - require __DIR__.'/../vendor/password.php'; -} diff --git a/app/common.php b/app/common.php index f46e3c6b..0ba7df9d 100644 --- a/app/common.php +++ b/app/common.php @@ -1,183 +1,32 @@ <?php +// Common file between cli and web interface + require __DIR__.'/Core/Loader.php'; require __DIR__.'/helpers.php'; -require __DIR__.'/translator.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'; -require __DIR__.'/../vendor/SimpleValidator/Validators/Numeric.php'; +require __DIR__.'/functions.php'; -use Core\Event; use Core\Loader; use Core\Registry; +// Include password_compat for PHP < 5.5 +if (version_compare(PHP_VERSION, '5.5.0', '<')) { + require __DIR__.'/../vendor/password.php'; +} + // 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); - -// Period (in second) to consider a task was modified recently -defined('RECENT_TASK_PERIOD') or define('RECENT_TASK_PERIOD', 48*60*60); - -// 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_SSL_VERIFY') or define('LDAP_SSL_VERIFY', true); -defined('LDAP_BIND_TYPE') or define('LDAP_BIND_TYPE', 'anonymous'); -defined('LDAP_USERNAME') or define('LDAP_USERNAME', null); -defined('LDAP_PASSWORD') or define('LDAP_PASSWORD', null); -defined('LDAP_ACCOUNT_BASE') or define('LDAP_ACCOUNT_BASE', ''); -defined('LDAP_USER_PATTERN') or define('LDAP_USER_PATTERN', ''); -defined('LDAP_ACCOUNT_FULLNAME') or define('LDAP_ACCOUNT_FULLNAME', 'displayname'); -defined('LDAP_ACCOUNT_EMAIL') or define('LDAP_ACCOUNT_EMAIL', 'mail'); - -// 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', ''); - -// GitHub authentication -defined('GITHUB_AUTH') or define('GITHUB_AUTH', false); -defined('GITHUB_CLIENT_ID') or define('GITHUB_CLIENT_ID', ''); -defined('GITHUB_CLIENT_SECRET') or define('GITHUB_CLIENT_SECRET', ''); - -// Proxy authentication -defined('REVERSE_PROXY_AUTH') or define('REVERSE_PROXY_AUTH', false); -defined('REVERSE_PROXY_USER_HEADER') or define('REVERSE_PROXY_USER_HEADER', 'REMOTE_USER'); -defined('REVERSE_PROXY_DEFAULT_ADMIN') or define('REVERSE_PROXY_DEFAULT_ADMIN', ''); -defined('REVERSE_PROXY_DEFAULT_DOMAIN') or define('REVERSE_PROXY_DEFAULT_DOMAIN', ''); - -// Mail configuration -defined('MAIL_FROM') or define('MAIL_FROM', 'notifications@kanboard.net'); -defined('MAIL_TRANSPORT') or define('MAIL_TRANSPORT', 'mail'); -defined('MAIL_SMTP_HOSTNAME') or define('MAIL_SMTP_HOSTNAME', ''); -defined('MAIL_SMTP_PORT') or define('MAIL_SMTP_PORT', 25); -defined('MAIL_SMTP_USERNAME') or define('MAIL_SMTP_USERNAME', ''); -defined('MAIL_SMTP_PASSWORD') or define('MAIL_SMTP_PASSWORD', ''); -defined('MAIL_SMTP_ENCRYPTION') or define('MAIL_SMTP_ENCRYPTION', null); -defined('MAIL_SENDMAIL_COMMAND') or define('MAIL_SENDMAIL_COMMAND', '/usr/sbin/sendmail -bs'); +require __DIR__.'/constants.php'; $loader = new Loader; +$loader->setPath('app'); +$loader->setPath('vendor'); $loader->execute(); $registry = new Registry; - -$registry->db = function() use ($registry) { - require __DIR__.'/../vendor/PicoDb/Database.php'; - - switch (DB_DRIVER) { - case 'sqlite': - require __DIR__.'/Schema/Sqlite.php'; - - $params = array( - 'driver' => 'sqlite', - 'filename' => DB_FILENAME - ); - - break; - - case 'mysql': - require __DIR__.'/Schema/Mysql.php'; - - $params = array( - 'driver' => 'mysql', - 'hostname' => DB_HOSTNAME, - 'username' => DB_USERNAME, - 'password' => DB_PASSWORD, - 'database' => DB_NAME, - 'charset' => 'utf8', - ); - - break; - - case 'postgres': - require __DIR__.'/Schema/Postgres.php'; - - $params = array( - 'driver' => 'postgres', - 'hostname' => DB_HOSTNAME, - 'username' => DB_USERNAME, - 'password' => DB_PASSWORD, - 'database' => DB_NAME, - ); - - break; - - default: - die('Database driver not supported'); - } - - $db = new \PicoDb\Database($params); - - if ($db->schema()->check(Schema\VERSION)) { - return $db; - } - else { - $errors = $db->getLogMessages(); - die('Unable to migrate database schema: <br/><br/><strong>'.(isset($errors[0]) ? $errors[0] : 'Unknown error').'</strong>'); - } -}; - -$registry->event = function() use ($registry) { - return new Event; -}; - -$registry->mailer = function() use ($registry) { - - require_once 'vendor/swiftmailer/swift_required.php'; - - switch (MAIL_TRANSPORT) { - case 'smtp': - $transport = Swift_SmtpTransport::newInstance(MAIL_SMTP_HOSTNAME, MAIL_SMTP_PORT); - $transport->setUsername(MAIL_SMTP_USERNAME); - $transport->setPassword(MAIL_SMTP_PASSWORD); - $transport->setEncryption(MAIL_SMTP_ENCRYPTION); - break; - case 'sendmail': - $transport = Swift_SendmailTransport::newInstance(MAIL_SENDMAIL_COMMAND); - break; - default: - $transport = Swift_MailTransport::newInstance(); - } - - return $transport; -}; +$registry->db = setup_db(); +$registry->event = setup_events(); +$registry->mailer = setup_mailer(); diff --git a/app/constants.php b/app/constants.php new file mode 100644 index 00000000..d52997d7 --- /dev/null +++ b/app/constants.php @@ -0,0 +1,70 @@ +<?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); + +// Period (in second) to consider a task was modified recently +defined('RECENT_TASK_PERIOD') or define('RECENT_TASK_PERIOD', 48*60*60); + +// 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_SSL_VERIFY') or define('LDAP_SSL_VERIFY', true); +defined('LDAP_BIND_TYPE') or define('LDAP_BIND_TYPE', 'anonymous'); +defined('LDAP_USERNAME') or define('LDAP_USERNAME', null); +defined('LDAP_PASSWORD') or define('LDAP_PASSWORD', null); +defined('LDAP_ACCOUNT_BASE') or define('LDAP_ACCOUNT_BASE', ''); +defined('LDAP_USER_PATTERN') or define('LDAP_USER_PATTERN', ''); +defined('LDAP_ACCOUNT_FULLNAME') or define('LDAP_ACCOUNT_FULLNAME', 'displayname'); +defined('LDAP_ACCOUNT_EMAIL') or define('LDAP_ACCOUNT_EMAIL', 'mail'); + +// 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', ''); + +// GitHub authentication +defined('GITHUB_AUTH') or define('GITHUB_AUTH', false); +defined('GITHUB_CLIENT_ID') or define('GITHUB_CLIENT_ID', ''); +defined('GITHUB_CLIENT_SECRET') or define('GITHUB_CLIENT_SECRET', ''); + +// Proxy authentication +defined('REVERSE_PROXY_AUTH') or define('REVERSE_PROXY_AUTH', false); +defined('REVERSE_PROXY_USER_HEADER') or define('REVERSE_PROXY_USER_HEADER', 'REMOTE_USER'); +defined('REVERSE_PROXY_DEFAULT_ADMIN') or define('REVERSE_PROXY_DEFAULT_ADMIN', ''); +defined('REVERSE_PROXY_DEFAULT_DOMAIN') or define('REVERSE_PROXY_DEFAULT_DOMAIN', ''); + +// Mail configuration +defined('MAIL_FROM') or define('MAIL_FROM', 'notifications@kanboard.net'); +defined('MAIL_TRANSPORT') or define('MAIL_TRANSPORT', 'mail'); +defined('MAIL_SMTP_HOSTNAME') or define('MAIL_SMTP_HOSTNAME', ''); +defined('MAIL_SMTP_PORT') or define('MAIL_SMTP_PORT', 25); +defined('MAIL_SMTP_USERNAME') or define('MAIL_SMTP_USERNAME', ''); +defined('MAIL_SMTP_PASSWORD') or define('MAIL_SMTP_PASSWORD', ''); +defined('MAIL_SMTP_ENCRYPTION') or define('MAIL_SMTP_ENCRYPTION', null); +defined('MAIL_SENDMAIL_COMMAND') or define('MAIL_SENDMAIL_COMMAND', '/usr/sbin/sendmail -bs'); diff --git a/app/functions.php b/app/functions.php new file mode 100644 index 00000000..4cbbbbfe --- /dev/null +++ b/app/functions.php @@ -0,0 +1,131 @@ +<?php + +use Core\Event; +use Core\Translator; +use PicoDb\Database; + +function debug($message) +{ + error_log($message.PHP_EOL, 3, 'data/debug.log'); +} + +function setup_events() +{ + return new Event; +} + +function setup_mailer() +{ + require_once __DIR__.'/../vendor/swiftmailer/swift_required.php'; + + switch (MAIL_TRANSPORT) { + case 'smtp': + $transport = Swift_SmtpTransport::newInstance(MAIL_SMTP_HOSTNAME, MAIL_SMTP_PORT); + $transport->setUsername(MAIL_SMTP_USERNAME); + $transport->setPassword(MAIL_SMTP_PASSWORD); + $transport->setEncryption(MAIL_SMTP_ENCRYPTION); + break; + case 'sendmail': + $transport = Swift_SendmailTransport::newInstance(MAIL_SENDMAIL_COMMAND); + break; + default: + $transport = Swift_MailTransport::newInstance(); + } + + return $transport; +} + +function setup_db() +{ + switch (DB_DRIVER) { + case 'sqlite': + require_once __DIR__.'/Schema/Sqlite.php'; + + $params = array( + 'driver' => 'sqlite', + 'filename' => DB_FILENAME + ); + + break; + + case 'mysql': + require_once __DIR__.'/Schema/Mysql.php'; + + $params = array( + 'driver' => 'mysql', + 'hostname' => DB_HOSTNAME, + 'username' => DB_USERNAME, + 'password' => DB_PASSWORD, + 'database' => DB_NAME, + 'charset' => 'utf8', + ); + + break; + + case 'postgres': + require_once __DIR__.'/Schema/Postgres.php'; + + $params = array( + 'driver' => 'postgres', + 'hostname' => DB_HOSTNAME, + 'username' => DB_USERNAME, + 'password' => DB_PASSWORD, + 'database' => DB_NAME, + ); + + break; + + default: + die('Database driver not supported'); + } + + $db = new Database($params); + + if ($db->schema()->check(Schema\VERSION)) { + return $db; + } + else { + $errors = $db->getLogMessages(); + die('Unable to migrate database schema: <br/><br/><strong>'.(isset($errors[0]) ? $errors[0] : 'Unknown error').'</strong>'); + } +} + +// Get a translation +function t() +{ + $t = new Translator; + return call_user_func_array(array($t, 'translate'), func_get_args()); +} + +// translate with no html escaping +function e() +{ + $t = new Translator; + return call_user_func_array(array($t, 'translateNoEscaping'), 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; +} diff --git a/app/translator.php b/app/translator.php deleted file mode 100644 index ac4d72e2..00000000 --- a/app/translator.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php - -use Core\Translator; - -// Get a translation -function t() -{ - $t = new Translator; - return call_user_func_array(array($t, 'translate'), func_get_args()); -} - -// translate with no html escaping -function e() -{ - $t = new Translator; - return call_user_func_array(array($t, 'translateNoEscaping'), 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; -} |