partkeepr

fork of partkeepr
git clone https://git.e1e0.net/partkeepr.git
Log | Files | Refs | Submodules | README | LICENSE

commit 61430195e93bdc6628d20ed189d665538d365fb5
parent 5932ec56ea66aa81dc4e71013dea24fd39727ac4
Author: Felicitus <felicitus@felicitus.org>
Date:   Sat, 31 Dec 2011 21:44:35 +0100

This is a multi-commit. I know, I shouldn't do such big commits.

Changes:
- Added cron logger (records if cron jobs are active)
- Setup now tells the user to create crons
- Added status bar icon for unacknowledged system notices
- Write out the config.php correctly for different data types

Diffstat:
Acronjobs/CheckForUpdates.php | 23+++++++++++++++++++++++
Mcronjobs/CreateStatisticSnapshot.php | 13+++++++------
Mcronjobs/UpdatePartCacheData.php | 8++++++--
Mcronjobs/UpdateTipsOfTheDay.php | 12++++++++----
Asrc/backend/de/RaumZeitLabor/PartKeepr/CronLogger/CronLogger.php | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/backend/de/RaumZeitLabor/PartKeepr/CronLogger/CronLoggerManager.php | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/backend/de/RaumZeitLabor/PartKeepr/PartKeepr.php | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
Asrc/backend/de/RaumZeitLabor/PartKeepr/Setup/MiscSettingsSetup.php | 35+++++++++++++++++++++++++++++++++++
Msrc/backend/de/RaumZeitLabor/PartKeepr/Setup/Setup.php | 3++-
Msrc/backend/de/RaumZeitLabor/PartKeepr/System/SystemService.php | 30+++++++++++++++++++++---------
Msrc/backend/de/RaumZeitLabor/PartKeepr/SystemNotice/SystemNotice.php | 33++++++++++++++++++++++++++++-----
Msrc/backend/de/RaumZeitLabor/PartKeepr/SystemNotice/SystemNoticeManager.php | 22++++++++++++++++++++++
Msrc/backend/de/RaumZeitLabor/PartKeepr/SystemNotice/SystemNoticeService.php | 13+++++++++++++
Msrc/backend/de/RaumZeitLabor/PartKeepr/Util/Configuration.php | 20+++++++++++++++++++-
Msrc/frontend/js/Components/Statusbar.js | 7++++++-
Rsrc/frontend/js/Components/ConnectionButton.js -> src/frontend/js/Components/Widgets/ConnectionButton.js | 0
Asrc/frontend/js/Components/Widgets/FadingButton.js | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/frontend/js/Components/Widgets/SystemNoticeButton.js | 15+++++++++++++++
Msrc/frontend/js/PartKeepr.js | 42++++++++++++++++++++++++++++++++++++------
Msrc/setup/index.html | 1+
Msrc/setup/js/Cards/DatabaseSetupCard.js | 1+
Asrc/setup/js/SetupSteps/MiscSetup.js | 15+++++++++++++++
Msrc/setup/js/SetupWizard.js | 11++++++++++-
Mtesting/SetupDatabase.php | 6------
24 files changed, 515 insertions(+), 56 deletions(-)

diff --git a/cronjobs/CheckForUpdates.php b/cronjobs/CheckForUpdates.php @@ -0,0 +1,22 @@ +<?php +/** + * Checks for PartKeepr updates + * Typically scheduled every one or two days. + * + * @author felicitus + * + */ +namespace de\RaumZeitLabor\PartKeepr\Cronjobs; + +declare(encoding = 'UTF-8'); + +include(__DIR__."/../src/backend/de/RaumZeitLabor/PartKeepr/PartKeepr.php"); + +use de\RaumZeitLabor\PartKeepr\PartKeepr, + de\RaumZeitLabor\PartKeepr\CronLogger\CronLoggerManager; + +PartKeepr::initialize(); + +PartKeepr::doVersionCheck(); + +CronLoggerManager::getInstance()->markCronRun(basename(__FILE__));+ \ No newline at end of file diff --git a/cronjobs/CreateStatisticSnapshot.php b/cronjobs/CreateStatisticSnapshot.php @@ -5,10 +5,11 @@ declare(encoding = 'UTF-8'); include(__DIR__."/../src/backend/de/RaumZeitLabor/PartKeepr/PartKeepr.php"); -use de\RaumZeitLabor\PartKeepr\PartKeepr; -use de\RaumZeitLabor\PartKeepr\Statistic\StatisticSnapshotManager; -PartKeepr::initialize(); - +use de\RaumZeitLabor\PartKeepr\PartKeepr, + de\RaumZeitLabor\PartKeepr\Statistic\StatisticSnapshotManager, + de\RaumZeitLabor\PartKeepr\CronLogger\CronLoggerManager; +PartKeepr::initialize(); +StatisticSnapshotManager::getInstance()->createSnapshot(); -StatisticSnapshotManager::getInstance()->createSnapshot();- \ No newline at end of file +CronLoggerManager::getInstance()->markCronRun(basename(__FILE__));+ \ No newline at end of file diff --git a/cronjobs/UpdatePartCacheData.php b/cronjobs/UpdatePartCacheData.php @@ -5,8 +5,10 @@ declare(encoding = 'UTF-8'); include(__DIR__."/../src/backend/de/RaumZeitLabor/PartKeepr/PartKeepr.php"); -use de\RaumZeitLabor\PartKeepr\PartKeepr; -use de\RaumZeitLabor\PartKeepr\Statistic\StatisticSnapshotManager; +use de\RaumZeitLabor\PartKeepr\PartKeepr, + de\RaumZeitLabor\PartKeepr\Statistic\StatisticSnapshotManager, + de\RaumZeitLabor\PartKeepr\CronLogger\CronLoggerManager; + PartKeepr::initialize(); $query = PartKeepr::getEM()->createQuery("SELECT p FROM de\RaumZeitLabor\PartKeepr\Part\Part p"); @@ -25,3 +27,4 @@ foreach ($result as $part) { PartKeepr::getEM()->flush(); +CronLoggerManager::getInstance()->markCronRun(basename(__FILE__));+ \ No newline at end of file diff --git a/cronjobs/UpdateTipsOfTheDay.php b/cronjobs/UpdateTipsOfTheDay.php @@ -14,8 +14,12 @@ declare(encoding = 'UTF-8'); include(__DIR__."/../src/backend/de/RaumZeitLabor/PartKeepr/PartKeepr.php"); -use de\RaumZeitLabor\PartKeepr\PartKeepr; -use de\RaumZeitLabor\PartKeepr\TipOfTheDay\TipOfTheDay; +use de\RaumZeitLabor\PartKeepr\PartKeepr, + de\RaumZeitLabor\PartKeepr\TipOfTheDay\TipOfTheDay, + de\RaumZeitLabor\PartKeepr\CronLogger\CronLoggerManager; + PartKeepr::initialize(); -TipOfTheDay::syncTips();- \ No newline at end of file +TipOfTheDay::syncTips(); + +CronLoggerManager::getInstance()->markCronRun(basename(__FILE__));+ \ No newline at end of file diff --git a/src/backend/de/RaumZeitLabor/PartKeepr/CronLogger/CronLogger.php b/src/backend/de/RaumZeitLabor/PartKeepr/CronLogger/CronLogger.php @@ -0,0 +1,59 @@ +<?php +namespace de\RaumZeitLabor\PartKeepr\CronLogger; +declare(encoding = 'UTF-8'); + +use de\RaumZeitLabor\PartKeepr\UploadedFile\UploadedFile, + de\RaumZeitLabor\PartKeepr\Util\BaseEntity, + de\RaumZeitLabor\PartKeepr\Util\Serializable, + de\RaumZeitLabor\PartKeepr\Util\Deserializable; + +/** + * Holds a project attachment + * @Entity + **/ +class CronLogger extends BaseEntity { + /** + * @Column(type="datetime") + * @var \DateTime + */ + private $lastRunDate; + + /** + * @Column(type="string") + * @var string + */ + private $cronjob; + + /** + * Sets the last run date and time for this entry + * @param \DateTime $date The date and time + */ + public function setLastRunDate (\DateTime $date) { + $this->lastRunDate = $date; + } + + /** + * Returns the date and time for this entry + * + * @return \DateTime the date and time for this entry + */ + public function getLastRunDate () { + return $this->lastRunDate; + } + + /** + * Sets the cronjob for this entry + * @param string $cronjob the title for this entry + */ + public function setCronjob ($cronjob) { + $this->cronjob = $cronjob; + } + + /** + * Returns the cronjob for this entry + * @return string the title + */ + public function getCronjob () { + return $this->cronjob; + } +}+ \ No newline at end of file diff --git a/src/backend/de/RaumZeitLabor/PartKeepr/CronLogger/CronLoggerManager.php b/src/backend/de/RaumZeitLabor/PartKeepr/CronLogger/CronLoggerManager.php @@ -0,0 +1,77 @@ +<?php +namespace de\RaumZeitLabor\PartKeepr\CronLogger; +declare(encoding = 'UTF-8'); + +use de\RaumZeitLabor\PartKeepr\Manager\AbstractManager, + de\RaumZeitLabor\PartKeepr\PartKeepr; + +class CronLoggerManager extends AbstractManager { + /** + * Returns the FQCN for the target entity to operate on. + * @return string The FQCN, e.g. de\RaumZeitLabor\PartKeepr\Part + */ + public function getEntityName () { + return 'de\RaumZeitLabor\PartKeepr\CronLogger\CronLogger'; + } + + /** + * Returns all fields which need to appear in the getList ResultSet. + * @return array An array of all fields which should be returned + */ + public function getQueryFields () { + return array("id", "title", "date"); + } + + /** + * Returns the default sort field + * + * @return string The default sort field + */ + public function getDefaultSortField () { + return "date"; + } + + public function markCronRun ($cronjob) { + $dql = "SELECT c FROM de\RaumZeitLabor\PartKeepr\CronLogger\CronLogger c WHERE c.cronjob = :cronjob"; + $query = PartKeepr::getEM()->createQuery($dql); + $query->setParameter("cronjob", $cronjob); + + try { + $result = $query->getSingleResult(); + } catch (\Exception $e) { + $result = new CronLogger(); + $result->setCronjob($cronjob); + PartKeepr::getEM()->persist($result); + } + + $result->setLastRunDate(new \DateTime()); + + PartKeepr::getEM()->flush(); + } + + public function getInactiveCronjobs () { + $dql = "SELECT c.cronjob FROM de\RaumZeitLabor\PartKeepr\CronLogger\CronLogger c WHERE c.cronjob = :cronjob"; + $dql .= " AND c.lastRunDate > :date"; + + $query = PartKeepr::getEM()->createQuery($dql); + + $date = new \DateTime(); + $date->sub(new \DateInterval('P1D')); + $query->setParameter("date", $date); + + $failedCronjobs = array(); + + foreach (PartKeepr::getRequiredCronjobs() as $cronjob) { + $query->setParameter("cronjob", $cronjob); + + try { + $query->getSingleResult(); + } catch (\Exception $e) { + $failedCronjobs[] = $cronjob; + } + + } + + return $failedCronjobs; + } +}+ \ No newline at end of file diff --git a/src/backend/de/RaumZeitLabor/PartKeepr/PartKeepr.php b/src/backend/de/RaumZeitLabor/PartKeepr/PartKeepr.php @@ -2,6 +2,7 @@ namespace de\RaumZeitLabor\PartKeepr; use Doctrine\Common\ClassLoader, + de\RaumZeitLabor\PartKeepr\SystemNotice\SystemNoticeManager, Doctrine\ORM\Configuration, Doctrine\ORM\EntityManager, de\RaumZeitLabor\PartKeepr\Util\Configuration as PartKeeprConfiguration; @@ -68,6 +69,19 @@ class PartKeepr { } + /** + * Returns an array of all cronjobs which are required for proper execution of PartKeepr. + * + * @return Array The filenames of each cronjob which is required + */ + public static function getRequiredCronjobs () { + return array( + "CreateStatisticSnapshot.php", + "UpdatePartCacheData.php", + "UpdateTipsOfTheDay.php", + "CheckForUpdates.php" + ); + } /** * Initializes the configuration for a given environment. @@ -88,6 +102,30 @@ class PartKeepr { } } + + /** + * Checks against the versions at partkeepr.org. + * + * If a newer version was found, create a system notice entry. + */ + public static function doVersionCheck () { + + $data = file_get_contents("http://www.partkeepr.org/versions.json"); + $versions = json_decode($data, true); + + if (PartKeeprVersion::PARTKEEPR_VERSION == "{V_GIT}") { return; } + + if (version_compare(PartKeepr::getVersion(), $versions[0]["version"], '<')) { + + SystemNoticeManager::getInstance()->createUniqueSystemNotice( + "PARTKEEPR_VERSION_".$versions[0]["version"], + sprintf(PartKeepr::i18n("New PartKeepr Version %s available"), $versions[0]["version"]), + sprintf(PartKeepr::i18n("PartKeepr Version %s changelog:"), $versions[0]["version"]) . "\n\n". + $versions[0]["changelog"] + ); + + } + } /** * Initializes the doctrine framework and @@ -238,6 +276,7 @@ class PartKeepr { 'de\RaumZeitLabor\PartKeepr\Project\Project', 'de\RaumZeitLabor\PartKeepr\Project\ProjectPart', + 'de\RaumZeitLabor\PartKeepr\Project\ProjectAttachment', 'de\RaumZeitLabor\PartKeepr\StorageLocation\StorageLocation', 'de\RaumZeitLabor\PartKeepr\StorageLocation\StorageLocationImage', @@ -264,7 +303,8 @@ class PartKeepr { 'de\RaumZeitLabor\PartKeepr\TipOfTheDay\TipOfTheDay', 'de\RaumZeitLabor\PartKeepr\TipOfTheDay\TipOfTheDayHistory', 'de\RaumZeitLabor\PartKeepr\UserPreference\UserPreference', - 'de\RaumZeitLabor\PartKeepr\SystemNotice\SystemNotice' + 'de\RaumZeitLabor\PartKeepr\SystemNotice\SystemNotice', + 'de\RaumZeitLabor\PartKeepr\CronLogger\CronLogger' ); } @@ -313,17 +353,27 @@ class PartKeepr { } return self::PARTKEEPR_VERSION; } + + /** + * This is a re-implementation of gettype(). + * + * The PHP documentation states that the "gettype" return values will change in the future, so we need + * to make sure we don't get bitten by the change. + * + * @param mixed $var + * @return string The type + */ + public static function getType($var) + { + if (is_array($var)) return "array"; + if (is_bool($var)) return "boolean"; + if (is_float($var)) return "float"; + if (is_int($var)) return "integer"; + if (is_null($var)) return "NULL"; + if (is_numeric($var)) return "numeric"; + if (is_object($var)) return "object"; + if (is_resource($var)) return "resource"; + if (is_string($var)) return "string"; + return "unknown type"; + } } - - - - - - - - - - - - - diff --git a/src/backend/de/RaumZeitLabor/PartKeepr/Setup/MiscSettingsSetup.php b/src/backend/de/RaumZeitLabor/PartKeepr/Setup/MiscSettingsSetup.php @@ -0,0 +1,34 @@ +<?php +namespace de\RaumZeitLabor\PartKeepr\Setup; + +use de\RaumZeitLabor\PartKeepr\CronLogger\CronLoggerManager, + de\RaumZeitLabor\PartKeepr\PartKeepr; + +/** + * Sets up misc stuff, which doesn't fit into other steps + */ +class MiscSettingsSetup extends AbstractSetup { + public function run () { + $this->markCronjobsAsRun(); + $this->clearAPCCache(); + } + + /** + * Marks the cronjobs as run, so that the user doesn't get an error during the first day. + * + * This is necessary because if the user sets up the system and enters the cronjobs, there is a chance + * that no cronjob has been ran when he logs in the first time and thus gets confused. + */ + public function markCronjobsAsRun () { + foreach (PartKeepr::getRequiredCronjobs() as $cronjob) { + CronLoggerManager::getInstance()->markCronRun($cronjob); + } + } + + public function clearAPCCache () { + if (function_exists("apc_clear_cache")) { + apc_clear_cache(); + apc_clear_cache("user"); + } + } +}+ \ No newline at end of file diff --git a/src/backend/de/RaumZeitLabor/PartKeepr/Setup/Setup.php b/src/backend/de/RaumZeitLabor/PartKeepr/Setup/Setup.php @@ -53,7 +53,8 @@ class Setup { "unit" => new UnitSetup($entityManager), "manufacturer" => new ManufacturerSetup($entityManager), "schemamigration" => new SchemaMigrationSetup($entityManager), - "configfile" => new ConfigFileSetup($entityManager) + "configfile" => new ConfigFileSetup($entityManager), + "miscsettings" => new MiscSettingsSetup($entityManager) ); if ($step == "all") { diff --git a/src/backend/de/RaumZeitLabor/PartKeepr/System/SystemService.php b/src/backend/de/RaumZeitLabor/PartKeepr/System/SystemService.php @@ -10,6 +10,7 @@ declare(encoding = 'UTF-8'); use de\RaumZeitLabor\PartKeepr\Service\Service; use de\RaumZeitLabor\PartKeepr\PartKeepr; +use de\RaumZeitLabor\PartKeepr\CronLogger\CronLoggerManager; class SystemService extends Service { /** @@ -64,17 +65,28 @@ class SystemService extends Service { * * Returns either status incomplete if the schema is not up-to-date, or complete if everything is OK. */ - public function getDatabaseSchemaStatus () { - $metadatas = PartKeepr::getEM()->getMetadataFactory()->getAllMetadata(); - - $schemaTool = new \Doctrine\ORM\Tools\SchemaTool(PartKeepr::getEM()); + public function getSystemStatus () { - $queries = $schemaTool->getUpdateSchemaSql($metadatas, true); + $inactiveCronjobs = CronLoggerManager::getInstance()->getInactiveCronjobs(); - if (count($queries) > 0) { - return array("data" => array("status" => "incomplete")); - } else { - return array("data" => array("status" => "complete")); + return array("data" => + array( + "inactiveCronjobCount" => count($inactiveCronjobs), + "inactiveCronjobs" => $inactiveCronjobs, + "schemaStatus" => $this->getSchemaStatus())); + } + + protected function getSchemaStatus () { + $metadatas = PartKeepr::getEM()->getMetadataFactory()->getAllMetadata(); + + $schemaTool = new \Doctrine\ORM\Tools\SchemaTool(PartKeepr::getEM()); + + $queries = $schemaTool->getUpdateSchemaSql($metadatas, true); + + if (count($queries) > 0) { + return "incomplete"; + } else { + return "complete"; } } } \ No newline at end of file diff --git a/src/backend/de/RaumZeitLabor/PartKeepr/SystemNotice/SystemNotice.php b/src/backend/de/RaumZeitLabor/PartKeepr/SystemNotice/SystemNotice.php @@ -8,7 +8,7 @@ use de\RaumZeitLabor\PartKeepr\UploadedFile\UploadedFile, de\RaumZeitLabor\PartKeepr\Util\Deserializable; /** - * Holds a project attachment + * Holds a system notice * @Entity **/ class SystemNotice extends BaseEntity implements Serializable { @@ -36,7 +36,14 @@ class SystemNotice extends BaseEntity implements Serializable { * @Column(type="boolean") * @var boolean */ - private $acknowledged; + private $acknowledged = false; + + /** + * Specifies the type. This is required for unique notices which shouldn't pop up every time we create them. + * @Column(type="string") + * @var string + */ + private $type; /** * Sets the date and time for this entry @@ -103,10 +110,26 @@ class SystemNotice extends BaseEntity implements Serializable { public function getAcknowledgedFlag () { return $this->acknowledged; } + + /** + * Sets the type of this entry + * @param string $type + */ + public function setType ($type) { + $this->type = $type; + } + + /** + * Returns the type of this entry + * @return string The type + */ + public function getType () { + return $this->type; + } + /** - * - * Serializes this project attachment - * @return array The serialized project attachment + * Serializes this system notice attachment + * @return array The serialized system notice */ public function serialize () { return array( diff --git a/src/backend/de/RaumZeitLabor/PartKeepr/SystemNotice/SystemNoticeManager.php b/src/backend/de/RaumZeitLabor/PartKeepr/SystemNotice/SystemNoticeManager.php @@ -31,4 +31,26 @@ class SystemNoticeManager extends AbstractManager { public function getDefaultSortField () { return "date"; } + + public function createUniqueSystemNotice ($type, $title, $description) { + $dql = "SELECT sn FROM de\RaumZeitLabor\PartKeepr\SystemNotice\SystemNotice sn WHERE sn.type = :type"; + $query = PartKeepr::getEM()->createQuery($dql); + + $query->setParameter("type", $type); + + try { + $notice = $query->getSingleResult(); + } catch (\Exception $e) { + $notice = new SystemNotice(); + PartKeepr::getEM()->persist($notice); + } + + $notice->setDate(new \DateTime()); + $notice->setTitle($title); + $notice->setDescription($description); + $notice->setType($type); + + PartKeepr::getEM()->flush(); + + } } \ No newline at end of file diff --git a/src/backend/de/RaumZeitLabor/PartKeepr/SystemNotice/SystemNoticeService.php b/src/backend/de/RaumZeitLabor/PartKeepr/SystemNotice/SystemNoticeService.php @@ -69,4 +69,17 @@ class SystemNoticeService extends Service implements RestfulService { $entity = SystemNoticeManager::getInstance()->getEntity($this->getParameter("id")); $entity->setAcknowledgedFlag(); } + + public function hasUnacknowledgedNotices () { + $dql = "SELECT COUNT(c) FROM de\RaumZeitLabor\PartKeepr\SystemNotice\SystemNotice c WHERE c.acknowledged = :a"; + $query = PartKeepr::getEM()->createQuery($dql); + $query->setParameter("a", false); + + $bRetval = false; + + if ($query->getSingleScalarResult() > 0) { + $bRetval = true; + } + return array("data" => array("unacknowledgedNotices" => $bRetval)); + } } \ No newline at end of file diff --git a/src/backend/de/RaumZeitLabor/PartKeepr/Util/Configuration.php b/src/backend/de/RaumZeitLabor/PartKeepr/Util/Configuration.php @@ -1,6 +1,8 @@ <?php namespace de\RaumZeitLabor\PartKeepr\Util; +use de\RaumZeitLabor\PartKeepr\PartKeepr; + /** * This class manages simple key -> value configurations within the system. * @@ -55,7 +57,23 @@ use de\RaumZeitLabor\PartKeepr\Util\Configuration; EOD; foreach (Configuration::$options as $option => $value) { - $config .= 'Configuration::setOption("'.$option.'", "'.$value.'");'."\n"; + switch (PartKeepr::getType($value)) { + case "string": + $config .= 'Configuration::setOption("'.$option.'", "'.$value.'");'."\n"; + break; + case "boolean": + $config .= 'Configuration::setOption("'.$option.'", '.($value === true ? 'true' : 'false').');'."\n"; + break; + case "integer": + $config .= 'Configuration::setOption("'.$option.'", '.intval($value).');'."\n"; + break; + case "float": + $config .= 'Configuration::setOption("'.$option.'", '.floatval($value).');'."\n"; + break; + default: + break; + } + } return $config; diff --git a/src/frontend/js/Components/Statusbar.js b/src/frontend/js/Components/Statusbar.js @@ -22,6 +22,10 @@ Ext.define('PartKeepr.Statusbar', { } }); + this.systemNoticeButton = Ext.create("PartKeepr.SystemNoticeButton", { + hidden: true + }); + Ext.apply(this, { items: [ this.currentUserDisplay, @@ -30,7 +34,8 @@ Ext.define('PartKeepr.Statusbar', { { xtype: 'tbseparator' }, this.showMessageLog, { xtype: 'tbseparator' }, - this.connectionButton + this.connectionButton, + this.systemNoticeButton ] }); diff --git a/src/frontend/js/Components/ConnectionButton.js b/src/frontend/js/Components/Widgets/ConnectionButton.js diff --git a/src/frontend/js/Components/Widgets/FadingButton.js b/src/frontend/js/Components/Widgets/FadingButton.js @@ -0,0 +1,44 @@ +Ext.define('PartKeepr.FadingButton', { + extend: 'Ext.Button', + initComponent: function () { + this.callParent(); + + }, + startFading: function () { + var iconEl = this.getEl().down(".x-btn-inner"); + + iconEl.animate({ + duration: 1000, + iterations: 1, // Should be enough for any session, + listeners: { + afteranimate: function () { + if (this.fadeRunning) { + // Not sure why defer is needed, but without it, it won't work. + Ext.defer(this.startFading, 100, this); + } + }, + scope: this + }, + keyframes: { + 50: { + opacity: 0 + }, + 100: { + opacity: 1 + } + }}); + this.fadeRunning = true; + }, + stopFading: function () { + this.fadeRunning = false; + }, + isFading: function () { + var iconEl = this.getEl().down(".x-btn-inner"); + + if (iconEl.getActiveAnimation() === false) { + return false; + } + + return true; + } +});+ \ No newline at end of file diff --git a/src/frontend/js/Components/Widgets/SystemNoticeButton.js b/src/frontend/js/Components/Widgets/SystemNoticeButton.js @@ -0,0 +1,14 @@ +Ext.define('PartKeepr.SystemNoticeButton', { + extend: 'PartKeepr.FadingButton', + icon: 'resources/fugue-icons/icons/service-bell.png', + tooltip: i18n("Unacknowledged System Notices"), + initComponent: function () { + this.callParent(); + + this.on("render", this.startFading, this); + this.on("click", this.onClick, this); + }, + onClick: function () { + PartKeepr.getApplication().menuBar.showSystemNotices(); + } +});+ \ No newline at end of file diff --git a/src/frontend/js/PartKeepr.js b/src/frontend/js/PartKeepr.js @@ -49,7 +49,8 @@ Ext.application({ this.addItem(j); this.menuBar.enable(); - this.doSchemaCheck(); + this.doSystemStatusCheck(); + this.doUnacknowledgedNoticesCheck(); /* Give the user preference stuff enough time to load */ /* @todo Load user preferences directly on login and not via delayed task */ @@ -89,20 +90,49 @@ Ext.application({ * @param none * @return nothing */ - doSchemaCheck: function () { - var call = new PartKeepr.ServiceCall("System", "getDatabaseSchemaStatus"); - call.setHandler(Ext.bind(this.onSchemaChecked, this)); + doSystemStatusCheck: function () { + var call = new PartKeepr.ServiceCall("System", "getSystemStatus"); + call.setHandler(Ext.bind(this.onSystemStatusCheck, this)); call.doCall(); }, /** * Handler for the schema check * @param data The data returned from the server */ - onSchemaChecked: function (data) { - if (data.data.status !== "complete") { + onSystemStatusCheck: function (data) { + if (data.data.schemaStatus !== "complete") { alert(i18n("Your database schema is not up-to-date! Please re-run setup immediately!")); } + + if (data.data.inactiveCronjobCount > 0) { + alert(i18n("The following cronjobs aren't running:")+"\n\n"+data.data.inactiveCronjobs.join("\n")); + } }, + /* + * Checks for unacknowledged system notices + * + * @param none + * @return nothing + */ + doUnacknowledgedNoticesCheck: function () { + var call = new PartKeepr.ServiceCall("SystemNotice", "hasUnacknowledgedNotices"); + + call.setHandler(Ext.bind(this.onUnacknowledgedNoticesCheck, this)); + call.doCall(); + }, + /** + * Handler for the unacknowledged system notices check + * @param data The data returned from the server + */ + onUnacknowledgedNoticesCheck: function (data) { + if (data.data.unacknowledgedNotices === true) { + this.statusBar.systemNoticeButton.show(); + } else { + this.statusBar.systemNoticeButton.hide(); + } + + Ext.defer(this.doUnacknowledgedNoticesCheck, 10000, this); + }, logout: function () { this.menuBar.disable(); this.centerPanel.removeAll(true); diff --git a/src/setup/index.html b/src/setup/index.html @@ -56,6 +56,7 @@ <script type="text/javascript" src="js/SetupSteps/FootprintSetup.js"></script> <script type="text/javascript" src="js/SetupSteps/SchemaMigrationSetup.js"></script> <script type="text/javascript" src="js/SetupSteps/ConfigFileSetup.js"></script> + <script type="text/javascript" src="js/SetupSteps/MiscSetup.js"></script> <script type="text/javascript" src="js/PartKeeprSetup.js"></script> </head> diff --git a/src/setup/js/Cards/DatabaseSetupCard.js b/src/setup/js/Cards/DatabaseSetupCard.js @@ -22,6 +22,7 @@ Ext.define('PartKeeprSetup.DatabaseSetupCard', { this.tests.push(new PartKeeprSetup.UnitSetup()); this.tests.push(new PartKeeprSetup.ManufacturerSetup()); this.tests.push(new PartKeeprSetup.SchemaMigrationSetup()); + this.tests.push(new PartKeeprSetup.MiscSetup()); this.tests.push(new PartKeeprSetup.ConfigFileSetup()); } }); diff --git a/src/setup/js/SetupSteps/MiscSetup.js b/src/setup/js/SetupSteps/MiscSetup.js @@ -0,0 +1,14 @@ +/** + * Sets up the default units + */ +Ext.define('PartKeeprSetup.MiscSetup', { + extend: 'PartKeeprSetup.AbstractTest', + url: 'setup.php', + name: "Database", + message: "Setting up misc settings", + + onBeforeRunTest: function () { + this.params = Ext.getCmp("database-parameters-card").dbparams; + this.params.step = "miscsettings"; + } +});+ \ No newline at end of file diff --git a/src/setup/js/SetupWizard.js b/src/setup/js/SetupWizard.js @@ -85,7 +85,16 @@ Ext.define('PartKeeprSetup.SetupWizard', { items: [{ border: false, bodyStyle: 'background:none;', - html: "<b>PartKeepr is now set-up.</b><br/><br/>If possible, set your web server's document root to the <b>frontend</b> directory.<br/><br/>To open PartKeepr, open the 'frontend' directory using your browser.<br/><br/>The default username/password combination is <b>admin/admin</b>" + html: "<b>PartKeepr is now set-up.</b><br/><br/>"+ + "Please set up the following cronjobs:<br/><br/><code>"+ + "0 0,24 * * * /usr/bin/php &lt;path-to-partkeepr&gt;/CreateStatisticSnapshot.php<br/>"+ + "0 0,6,12,18 * * * /usr/bin/php &lt;path-to-partkeepr&gt;/UpdatePartCacheData.php<br/>"+ + "0 0 */2 * * /usr/bin/php &lt;path-to-partkeepr&gt;/CheckForUpdates.php<br/>"+ + "0 0 */2 * * /usr/bin/php &lt;path-to-partkeepr&gt;/UpdateTipsOfTheDay.php<br/>"+ + "</code><br/><br/>"+ + "If possible, set your web server's document root to the <b>frontend</b> directory.<br/><br/>"+ + "To open PartKeepr, open the 'frontend' directory using your browser.<br/><br/>"+ + "The default username/password combination is <b>admin/admin</b>" }] })); diff --git a/testing/SetupDatabase.php b/testing/SetupDatabase.php @@ -98,9 +98,3 @@ if ($migration) { echo "All done.\n\n"; echo "Use the user 'admin' with password 'admin' to login. Access the frontend using the `frontend` directory.\n"; - -apc_clear_cache(); -apc_clear_cache("user"); - - -?>