diff options
Diffstat (limited to 'app/Core')
-rw-r--r-- | app/Core/Base.php | 16 | ||||
-rw-r--r-- | app/Core/DateParser.php | 9 | ||||
-rw-r--r-- | app/Core/ExternalTask/ExternalTaskManager.php | 7 | ||||
-rw-r--r-- | app/Core/Filter/FormatterInterface.php | 2 | ||||
-rw-r--r-- | app/Core/Helper.php | 1 | ||||
-rw-r--r-- | app/Core/Http/Request.php | 15 | ||||
-rw-r--r-- | app/Core/Mail/Transport/Mail.php | 4 | ||||
-rw-r--r-- | app/Core/Mail/Transport/Smtp.php | 1 | ||||
-rw-r--r-- | app/Core/Paginator.php | 45 | ||||
-rw-r--r-- | app/Core/Plugin/Base.php | 13 | ||||
-rw-r--r-- | app/Core/Plugin/Directory.php | 13 | ||||
-rw-r--r-- | app/Core/Plugin/Loader.php | 48 | ||||
-rw-r--r-- | app/Core/Plugin/PluginException.php | 15 | ||||
-rw-r--r-- | app/Core/Plugin/PluginInstallerException.php | 4 | ||||
-rw-r--r-- | app/Core/Plugin/Version.php | 38 | ||||
-rw-r--r-- | app/Core/Queue/QueueManager.php | 2 | ||||
-rw-r--r-- | app/Core/Tool.php | 25 |
17 files changed, 215 insertions, 43 deletions
diff --git a/app/Core/Base.php b/app/Core/Base.php index 881cccbd..17ed5b33 100644 --- a/app/Core/Base.php +++ b/app/Core/Base.php @@ -62,6 +62,21 @@ use Pimple\Container; * @property \Kanboard\Decorator\ColumnRestrictionCacheDecorator $columnRestrictionCacheDecorator * @property \Kanboard\Decorator\ColumnMoveRestrictionCacheDecorator $columnMoveRestrictionCacheDecorator * @property \Kanboard\Decorator\ProjectRoleRestrictionCacheDecorator $projectRoleRestrictionCacheDecorator + * @property \Kanboard\Formatter\BoardColumnFormatter $boardColumnFormatter + * @property \Kanboard\Formatter\BoardFormatter $boardFormatter + * @property \Kanboard\Formatter\BoardSwimlaneFormatter $boardSwimlaneFormatter + * @property \Kanboard\Formatter\BoardTaskFormatter $boardTaskFormatter + * @property \Kanboard\Formatter\GroupAutoCompleteFormatter $groupAutoCompleteFormatter + * @property \Kanboard\Formatter\ProjectActivityEventFormatter $projectActivityEventFormatter + * @property \Kanboard\Formatter\ProjectGanttFormatter $projectGanttFormatter + * @property \Kanboard\Formatter\SubtaskTimeTrackingCalendarFormatter $subtaskTimeTrackingCalendarFormatter + * @property \Kanboard\Formatter\TaskAutoCompleteFormatter $taskAutoCompleteFormatter + * @property \Kanboard\Formatter\TaskCalendarFormatter $taskCalendarFormatter + * @property \Kanboard\Formatter\TaskGanttFormatter $taskGanttFormatter + * @property \Kanboard\Formatter\TaskICalFormatter $taskICalFormatter + * @property \Kanboard\Formatter\TaskSuggestMenuFormatter $taskSuggestMenuFormatter + * @property \Kanboard\Formatter\UserAutoCompleteFormatter $userAutoCompleteFormatter + * @property \Kanboard\Formatter\UserMentionFormatter $userMentionFormatter * @property \Kanboard\Model\ActionModel $actionModel * @property \Kanboard\Model\ActionParameterModel $actionParameterModel * @property \Kanboard\Model\AvatarFileModel $avatarFileModel @@ -79,6 +94,7 @@ use Pimple\Container; * @property \Kanboard\Model\ProjectFileModel $projectFileModel * @property \Kanboard\Model\GroupModel $groupModel * @property \Kanboard\Model\GroupMemberModel $groupMemberModel + * @property \Kanboard\Model\InviteModel $inviteModel * @property \Kanboard\Model\LanguageModel $languageModel * @property \Kanboard\Model\LastLoginModel $lastLoginModel * @property \Kanboard\Model\LinkModel $linkModel diff --git a/app/Core/DateParser.php b/app/Core/DateParser.php index b9aa9230..9d012d12 100644 --- a/app/Core/DateParser.php +++ b/app/Core/DateParser.php @@ -13,7 +13,6 @@ use DateTime; class DateParser extends Base { const DATE_FORMAT = 'm/d/Y'; - const DATE_TIME_FORMAT = 'm/d/Y H:i'; const TIME_FORMAT = 'H:i'; /** @@ -35,7 +34,7 @@ class DateParser extends Base */ public function getUserDateTimeFormat() { - return $this->configModel->get('application_datetime_format', DateParser::DATE_TIME_FORMAT); + return $this->getUserDateFormat().' '.$this->getUserTimeFormat(); } /** @@ -292,11 +291,9 @@ class DateParser extends Base { foreach ($fields as $field) { if (! empty($values[$field])) { - if (! ctype_digit($values[$field])) { - $values[$field] = strtotime($values[$field]); + if (ctype_digit($values[$field])) { + $values[$field] = date($format, $values[$field]); } - - $values[$field] = date($format, $values[$field]); } else { $values[$field] = ''; } diff --git a/app/Core/ExternalTask/ExternalTaskManager.php b/app/Core/ExternalTask/ExternalTaskManager.php index 2ce6f106..102ec459 100644 --- a/app/Core/ExternalTask/ExternalTaskManager.php +++ b/app/Core/ExternalTask/ExternalTaskManager.php @@ -48,6 +48,11 @@ class ExternalTaskManager public function getProvidersList() { $providers = array_keys($this->providers); - return array_combine($providers, $providers); + + if (count($providers)) { + return array_combine($providers, $providers); + } + + return array(); } } diff --git a/app/Core/Filter/FormatterInterface.php b/app/Core/Filter/FormatterInterface.php index b7c04c51..0ff84976 100644 --- a/app/Core/Filter/FormatterInterface.php +++ b/app/Core/Filter/FormatterInterface.php @@ -17,7 +17,7 @@ interface FormatterInterface * * @access public * @param Table $query - * @return FormatterInterface + * @return $this */ public function withQuery(Table $query); diff --git a/app/Core/Helper.php b/app/Core/Helper.php index 9660c348..ab7c3b7b 100644 --- a/app/Core/Helper.php +++ b/app/Core/Helper.php @@ -20,6 +20,7 @@ use Pimple\Container; * @property \Kanboard\Helper\FormHelper $form * @property \Kanboard\Helper\HookHelper $hook * @property \Kanboard\Helper\ICalHelper $ical + * @property \Kanboard\Helper\ModalHelper $modal * @property \Kanboard\Helper\ModelHelper $model * @property \Kanboard\Helper\SubtaskHelper $subtask * @property \Kanboard\Helper\TaskHelper $task diff --git a/app/Core/Http/Request.php b/app/Core/Http/Request.php index 2e84958d..44bfdbe6 100644 --- a/app/Core/Http/Request.php +++ b/app/Core/Http/Request.php @@ -105,7 +105,7 @@ class Request extends Base { if (! empty($this->post) && ! empty($this->post['csrf_token']) && $this->token->validateCSRFToken($this->post['csrf_token'])) { unset($this->post['csrf_token']); - return $this->post; + return $this->filterValues($this->post); } return array(); @@ -344,4 +344,17 @@ class Request extends Base { return isset($this->server[$variable]) ? $this->server[$variable] : ''; } + + protected function filterValues(array $values) + { + foreach ($values as $key => $value) { + + // IE11 Workaround when submitting multipart/form-data + if (strpos($key, '-----------------------------') === 0) { + unset($values[$key]); + } + } + + return $values; + } } diff --git a/app/Core/Mail/Transport/Mail.php b/app/Core/Mail/Transport/Mail.php index d27925f0..c99cc8ba 100644 --- a/app/Core/Mail/Transport/Mail.php +++ b/app/Core/Mail/Transport/Mail.php @@ -33,8 +33,8 @@ class Mail extends Base implements ClientInterface $message = Swift_Message::newInstance() ->setSubject($subject) ->setFrom(array($this->helper->mail->getMailSenderAddress() => $author)) - ->setBody($html, 'text/html') - ->setTo(array($email => $name)); + ->setTo(array($email => $name)) + ->setBody($html, 'text/html'); Swift_Mailer::newInstance($this->getTransport())->send($message); } catch (Swift_TransportException $e) { diff --git a/app/Core/Mail/Transport/Smtp.php b/app/Core/Mail/Transport/Smtp.php index 1f4e54ce..815dde5d 100644 --- a/app/Core/Mail/Transport/Smtp.php +++ b/app/Core/Mail/Transport/Smtp.php @@ -24,6 +24,7 @@ class Smtp extends Mail $transport->setUsername(MAIL_SMTP_USERNAME); $transport->setPassword(MAIL_SMTP_PASSWORD); $transport->setEncryption(MAIL_SMTP_ENCRYPTION); + if (HTTP_VERIFY_SSL_CERTIFICATE === false) { $transport->setStreamOptions(array( 'ssl' => array( diff --git a/app/Core/Paginator.php b/app/Core/Paginator.php index cfe89938..9075a713 100644 --- a/app/Core/Paginator.php +++ b/app/Core/Paginator.php @@ -232,6 +232,17 @@ class Paginator } /** + * Get the number of current page + * + * @access public + * @return integer + */ + public function getPage() + { + return $this->page; + } + + /** * Set the default column order * * @access public @@ -271,6 +282,16 @@ class Paginator } /** + * Get the maximum number of items per page. + * + * @return int + */ + public function getMax() + { + return $this->limit; + } + + /** * Return true if the collection is empty * * @access public @@ -353,7 +374,9 @@ class Paginator '← '.t('Previous'), $this->controller, $this->action, - $this->getUrlParams($this->page - 1, $this->order, $this->direction) + $this->getUrlParams($this->page - 1, $this->order, $this->direction), + false, + 'js-modal-replace' ); } else { $html .= '← '.t('Previous'); @@ -379,7 +402,9 @@ class Paginator t('Next').' →', $this->controller, $this->action, - $this->getUrlParams($this->page + 1, $this->order, $this->direction) + $this->getUrlParams($this->page + 1, $this->order, $this->direction), + false, + 'js-modal-replace' ); } else { $html .= t('Next').' →'; @@ -391,6 +416,17 @@ class Paginator } /** + * Generate the page showing. + * + * @access public + * @return string + */ + public function generatPageShowing() + { + return '<span class="pagination-showing">'.t('Showing %d-%d of %d', (($this->getPage() - 1) * $this->getMax() + 1), min($this->getTotal(), $this->getPage() * $this->getMax()), $this->getTotal()).'</span>'; + } + + /** * Return true if there is no pagination to show * * @access public @@ -413,6 +449,7 @@ class Paginator if (! $this->hasNothingtoShow()) { $html .= '<div class="pagination">'; + $html .= $this->generatPageShowing(); $html .= $this->generatePreviousLink(); $html .= $this->generateNextLink(); $html .= '</div>'; @@ -453,7 +490,9 @@ class Paginator $label, $this->controller, $this->action, - $this->getUrlParams($this->page, $column, $direction) + $this->getUrlParams($this->page, $column, $direction), + false, + 'js-modal-replace' ); } } diff --git a/app/Core/Plugin/Base.php b/app/Core/Plugin/Base.php index 9d8167a9..e0b5954a 100644 --- a/app/Core/Plugin/Base.php +++ b/app/Core/Plugin/Base.php @@ -131,4 +131,17 @@ abstract class Base extends \Kanboard\Core\Base { return ''; } + + /** + * Get application compatibility version + * + * Examples: >=1.0.36, 1.0.37, APP_VERSION + * + * @access public + * @return string + */ + public function getCompatibleVersion() + { + return APP_VERSION; + } } diff --git a/app/Core/Plugin/Directory.php b/app/Core/Plugin/Directory.php index 27c3514e..dc32e655 100644 --- a/app/Core/Plugin/Directory.php +++ b/app/Core/Plugin/Directory.php @@ -36,18 +36,7 @@ class Directory extends BaseCore */ public function isCompatible(array $plugin, $appVersion = APP_VERSION) { - if (strpos($appVersion, 'master') !== false) { - return true; - } - - foreach (array('>=', '>') as $operator) { - if (strpos($plugin['compatible_version'], $operator) === 0) { - $pluginVersion = substr($plugin['compatible_version'], strlen($operator)); - return version_compare($appVersion, $pluginVersion, $operator); - } - } - - return $plugin['compatible_version'] === $appVersion; + return Version::isCompatible($plugin['compatible_version'], $appVersion); } /** diff --git a/app/Core/Plugin/Loader.php b/app/Core/Plugin/Loader.php index f2f6add7..38f41d39 100644 --- a/app/Core/Plugin/Loader.php +++ b/app/Core/Plugin/Loader.php @@ -4,6 +4,7 @@ namespace Kanboard\Core\Plugin; use Composer\Autoload\ClassLoader; use DirectoryIterator; +use Exception; use LogicException; use Kanboard\Core\Tool; @@ -22,6 +23,7 @@ class Loader extends \Kanboard\Core\Base * @var array */ protected $plugins = array(); + protected $incompatiblePlugins = array(); /** * Get list of loaded plugins @@ -35,6 +37,17 @@ class Loader extends \Kanboard\Core\Base } /** + * Get list of not compatible plugins + * + * @access public + * @return Base[] + */ + public function getIncompatiblePlugins() + { + return $this->incompatiblePlugins; + } + + /** * Scan plugin folder and load plugins * * @access public @@ -51,8 +64,7 @@ class Loader extends \Kanboard\Core\Base foreach ($dir as $fileInfo) { if ($fileInfo->isDir() && substr($fileInfo->getFilename(), 0, 1) !== '.') { $pluginName = $fileInfo->getFilename(); - $this->loadSchema($pluginName); - $this->initializePlugin($pluginName, $this->loadPlugin($pluginName)); + $this->initializePlugin($pluginName); } } } @@ -85,7 +97,7 @@ class Loader extends \Kanboard\Core\Base $className = '\Kanboard\Plugin\\'.$pluginName.'\\Plugin'; if (! class_exists($className)) { - throw new LogicException('Unable to load this plugin class '.$className); + throw new LogicException('Unable to load this plugin class: '.$className); } return new $className($this->container); @@ -96,18 +108,30 @@ class Loader extends \Kanboard\Core\Base * * @access public * @param string $pluginName - * @param Base $plugin */ - public function initializePlugin($pluginName, Base $plugin) + public function initializePlugin($pluginName) { - if (method_exists($plugin, 'onStartup')) { - $this->dispatcher->addListener('app.bootstrap', array($plugin, 'onStartup')); - } + try { + $plugin = $this->loadPlugin($pluginName); - Tool::buildDIC($this->container, $plugin->getClasses()); - Tool::buildDICHelpers($this->container, $plugin->getHelpers()); + if (Version::isCompatible($plugin->getCompatibleVersion(), APP_VERSION)) { + $this->loadSchema($pluginName); + + if (method_exists($plugin, 'onStartup')) { + $this->dispatcher->addListener('app.bootstrap', array($plugin, 'onStartup')); + } - $plugin->initialize(); - $this->plugins[$pluginName] = $plugin; + Tool::buildDIC($this->container, $plugin->getClasses()); + Tool::buildDICHelpers($this->container, $plugin->getHelpers()); + + $plugin->initialize(); + $this->plugins[$pluginName] = $plugin; + } else { + $this->incompatiblePlugins[$pluginName] = $plugin; + $this->logger->error($pluginName.' is not compatible with this version'); + } + } catch (Exception $e) { + $this->logger->critical($pluginName.': '.$e->getMessage()); + } } } diff --git a/app/Core/Plugin/PluginException.php b/app/Core/Plugin/PluginException.php new file mode 100644 index 00000000..fae7de35 --- /dev/null +++ b/app/Core/Plugin/PluginException.php @@ -0,0 +1,15 @@ +<?php + +namespace Kanboard\Core\Plugin; + +use Exception; + +/** + * Class PluginException + * + * @package Kanboard\Core\Plugin + * @author Frederic Guillot + */ +class PluginException extends Exception +{ +} diff --git a/app/Core/Plugin/PluginInstallerException.php b/app/Core/Plugin/PluginInstallerException.php index 7d356c9b..31745f22 100644 --- a/app/Core/Plugin/PluginInstallerException.php +++ b/app/Core/Plugin/PluginInstallerException.php @@ -2,14 +2,12 @@ namespace Kanboard\Core\Plugin; -use Exception; - /** * Class PluginInstallerException * * @package Kanboard\Core\Plugin * @author Frederic Guillot */ -class PluginInstallerException extends Exception +class PluginInstallerException extends PluginException { } diff --git a/app/Core/Plugin/Version.php b/app/Core/Plugin/Version.php new file mode 100644 index 00000000..ba5e0443 --- /dev/null +++ b/app/Core/Plugin/Version.php @@ -0,0 +1,38 @@ +<?php + +namespace Kanboard\Core\Plugin; + +/** + * Class Version + * + * @package Kanboard\Core\Plugin + * @author Frederic Guillot + */ +class Version +{ + /** + * Check plugin version compatibility with application version + * + * @param string $pluginCompatibleVersion + * @param string $appVersion + * @return bool + */ + public static function isCompatible($pluginCompatibleVersion, $appVersion = APP_VERSION) + { + if (strpos($appVersion, 'master') !== false) { + return true; + } + + $appVersion = str_replace('v', '', $appVersion); + $pluginCompatibleVersion = str_replace('v', '', $pluginCompatibleVersion); + + foreach (array('>=', '>', '<=', '<') as $operator) { + if (strpos($pluginCompatibleVersion, $operator) === 0) { + $pluginVersion = substr($pluginCompatibleVersion, strlen($operator)); + return version_compare($appVersion, $pluginVersion, $operator); + } + } + + return $pluginCompatibleVersion === $appVersion; + } +} diff --git a/app/Core/Queue/QueueManager.php b/app/Core/Queue/QueueManager.php index dcf0ebf5..1d7c2d1e 100644 --- a/app/Core/Queue/QueueManager.php +++ b/app/Core/Queue/QueueManager.php @@ -64,7 +64,7 @@ class QueueManager extends Base public function listen() { if ($this->queue === null) { - throw new LogicException('No queue driver defined!'); + throw new LogicException('No queue driver defined or unable to connect to broker!'); } while ($job = $this->queue->pull()) { diff --git a/app/Core/Tool.php b/app/Core/Tool.php index 9b8820eb..6e457641 100644 --- a/app/Core/Tool.php +++ b/app/Core/Tool.php @@ -41,7 +41,7 @@ class Tool } /** - * Build dependency injection container from an array + * Build dependency injection containers from an array * * @static * @access public @@ -64,6 +64,29 @@ class Tool } /** + * Build dependency injection container from an array + * + * @static + * @access public + * @param Container $container + * @param array $namespaces + * @return Container + */ + public static function buildFactories(Container $container, array $namespaces) + { + foreach ($namespaces as $namespace => $classes) { + foreach ($classes as $name) { + $class = '\\Kanboard\\'.$namespace.'\\'.$name; + $container[lcfirst($name)] = $container->factory(function ($c) use ($class) { + return new $class($c); + }); + } + } + + return $container; + } + + /** * Build dependency injection container for custom helpers from an array * * @static |