partkeepr

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

commit ff70e1f722544b86a6cfad526a33f15997a909bf
parent 478ba77657551e5affff690d24660aff59d71566
Author: Felicia Hummel <felicitus@felicitus.org>
Date:   Tue,  2 Aug 2016 14:31:21 +0200

Merge pull request #699 from partkeepr/PartKeepr-501

Part keepr 501
Diffstat:
M.styleci.yml | 1+
M.travis.yml | 2+-
Mapp/AppKernel.php | 1+
Mapp/SymfonyRequirements.php | 15++++++++-------
Mapp/check.php | 18+++++++++---------
Mapp/config/config_partkeepr.yml | 48++++++++++++++++++++++++++++++++++++++++++++++++
Mcomposer.lock | 20++++++++++----------
Msrc/PartKeepr/DoctrineReflectionBundle/Filter/AdvancedSearchFilter.php | 40++++++++++++++++++++--------------------
Msrc/PartKeepr/DoctrineReflectionBundle/Filter/AssociationPropertyInterface.php | 2+-
Msrc/PartKeepr/DoctrineReflectionBundle/Filter/AssociationPropertyTrait.php | 4+---
Msrc/PartKeepr/DoctrineReflectionBundle/Filter/Filter.php | 24++++++++----------------
Dsrc/PartKeepr/DoctrineReflectionBundle/Filter/PropertyFilter.php | 16----------------
Msrc/PartKeepr/DoctrineReflectionBundle/Filter/Sorter.php | 4+++-
Msrc/PartKeepr/FrontendBundle/Resources/public/js/Components/Editor/EditorGrid.js | 41++++++++++++++++++++++++++++-------------
Msrc/PartKeepr/FrontendBundle/Resources/public/js/Components/MenuBar.js | 24++++++++++++------------
Msrc/PartKeepr/FrontendBundle/Resources/public/js/Components/Part/PartsGrid.js | 6+++++-
Asrc/PartKeepr/FrontendBundle/Resources/public/js/Components/SystemPreferences/Panel.js | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/PartKeepr/FrontendBundle/Resources/public/js/Components/SystemPreferences/PreferenceEditor.js | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/PartKeepr/FrontendBundle/Resources/public/js/Components/SystemPreferences/Preferences/FulltextSearch.js | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/PartKeepr/FrontendBundle/Resources/public/js/Components/SystemPreferences/Tree.js | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/PartKeepr/FrontendBundle/Resources/public/js/Components/Widgets/FieldSelector.js | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/PartKeepr/FrontendBundle/Resources/public/js/Data/store/SystemPreferenceStore.js | 20++++++++++++++++++++
Msrc/PartKeepr/FrontendBundle/Resources/public/js/PartKeepr.js | 229+++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/PartKeepr/FrontendBundle/Resources/public/js/form/field/SearchField.js | 120+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
Msrc/PartKeepr/FrontendBundle/Resources/views/index.html.twig | 6++++++
Asrc/PartKeepr/SystemPreferenceBundle/Action/DeletePreferenceAction.php | 47+++++++++++++++++++++++++++++++++++++++++++++++
Asrc/PartKeepr/SystemPreferenceBundle/Action/GetPreferencesAction.php | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/PartKeepr/SystemPreferenceBundle/Action/SetPreferenceAction.php | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/PartKeepr/SystemPreferenceBundle/DependencyInjection/Configuration.php | 24++++++++++++++++++++++++
Asrc/PartKeepr/SystemPreferenceBundle/DependencyInjection/PartKeeprSystemPreferenceExtension.php | 24++++++++++++++++++++++++
Asrc/PartKeepr/SystemPreferenceBundle/Entity/SystemPreference.php | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/PartKeepr/SystemPreferenceBundle/Exceptions/SystemPreferenceNotFoundException.php | 15+++++++++++++++
Asrc/PartKeepr/SystemPreferenceBundle/PartKeeprSystemPreferenceBundle.php | 9+++++++++
Asrc/PartKeepr/SystemPreferenceBundle/Resources/config/actions.xml | 22++++++++++++++++++++++
Asrc/PartKeepr/SystemPreferenceBundle/Resources/config/services.xml | 12++++++++++++
Asrc/PartKeepr/SystemPreferenceBundle/Service/SystemPreferenceService.php | 123+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/PartKeepr/SystemPreferenceBundle/Tests/SystemPreferenceTest.php | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
37 files changed, 1285 insertions(+), 268 deletions(-)

diff --git a/.styleci.yml b/.styleci.yml @@ -2,3 +2,4 @@ preset: recommended disabled: - phpdoc_to_comment + - single_quote diff --git a/.travis.yml b/.travis.yml @@ -6,7 +6,7 @@ php: - nightly script: - - phpunit -c app/ --coverage-clover build/logs/clover.xml + - vendor/bin/phpunit -c app/ --coverage-clover build/logs/clover.xml env: - SYMFONY__TESTDB=mysql diff --git a/app/AppKernel.php b/app/AppKernel.php @@ -63,6 +63,7 @@ class AppKernel extends Kernel $bundles[] = new PartKeepr\TipOfTheDayBundle\PartKeeprTipOfTheDayBundle(); $bundles[] = new PartKeepr\ExportBundle\PartKeeprExportBundle(); $bundles[] = new PartKeepr\StatisticBundle\PartKeeprStatisticBundle(); + $bundles[] = new PartKeepr\SystemPreferenceBundle\PartKeeprSystemPreferenceBundle(); return array_merge($bundles, $this->getCustomBundles()); } diff --git a/app/SymfonyRequirements.php b/app/SymfonyRequirements.php @@ -168,7 +168,7 @@ class PhpIniRequirement extends Requirement */ class RequirementCollection implements IteratorAggregate { - private $requirements = []; + private $requirements = array(); /** * Gets the current RequirementCollection as an Iterator. @@ -279,7 +279,7 @@ class RequirementCollection implements IteratorAggregate */ public function getRequirements() { - $array = []; + $array = array(); foreach ($this->requirements as $req) { if (!$req->isOptional()) { $array[] = $req; @@ -296,7 +296,7 @@ class RequirementCollection implements IteratorAggregate */ public function getFailedRequirements() { - $array = []; + $array = array(); foreach ($this->requirements as $req) { if (!$req->isFulfilled() && !$req->isOptional()) { $array[] = $req; @@ -313,7 +313,7 @@ class RequirementCollection implements IteratorAggregate */ public function getRecommendations() { - $array = []; + $array = array(); foreach ($this->requirements as $req) { if ($req->isOptional()) { $array[] = $req; @@ -330,7 +330,7 @@ class RequirementCollection implements IteratorAggregate */ public function getFailedRecommendations() { - $array = []; + $array = array(); foreach ($this->requirements as $req) { if (!$req->isFulfilled() && $req->isOptional()) { $array[] = $req; @@ -432,7 +432,7 @@ class SymfonyRequirements extends RequirementCollection ); if (version_compare($installedPhpVersion, self::REQUIRED_PHP_VERSION, '>=')) { - $timezones = []; + $timezones = array(); foreach (DateTimeZone::listAbbreviations() as $abbreviations) { foreach ($abbreviations as $abbreviation) { $timezones[$abbreviation['timezone_id']] = true; @@ -697,7 +697,8 @@ class SymfonyRequirements extends RequirementCollection || (extension_loaded('xcache') && ini_get('xcache.cacher')) || - (extension_loaded('wincache') && ini_get('wincache.ocenabled')); + (extension_loaded('wincache') && ini_get('wincache.ocenabled')) + ; $this->addRecommendation( $accelerator, diff --git a/app/check.php b/app/check.php @@ -19,7 +19,7 @@ echo PHP_EOL.PHP_EOL; echo '> Checking Symfony requirements:'.PHP_EOL.' '; -$messages = []; +$messages = array(); foreach ($symfonyRequirements->getRequirements() as $req) { /** @var $req Requirement */ if ($helpText = get_error_message($req, $lineSize)) { @@ -99,15 +99,15 @@ function echo_title($title, $style = null) function echo_style($style, $message) { // ANSI color codes - $styles = [ - 'reset' => "\033[0m", - 'red' => "\033[31m", - 'green' => "\033[32m", - 'yellow' => "\033[33m", - 'error' => "\033[37;41m", + $styles = array( + 'reset' => "\033[0m", + 'red' => "\033[31m", + 'green' => "\033[32m", + 'yellow' => "\033[33m", + 'error' => "\033[37;41m", 'success' => "\033[37;42m", - 'title' => "\033[34m", - ]; + 'title' => "\033[34m", + ); $supports = has_color_support(); echo($supports ? $styles[$style] : '').$message.($supports ? $styles['reset'] : ''); diff --git a/app/config/config_partkeepr.yml b/app/config/config_partkeepr.yml @@ -1238,3 +1238,50 @@ services: arguments: - { groups: [ "default" ] } + resource.system_preference.item_operation.get_preferences: + class: "Dunglas\ApiBundle\Api\Operation\Operation" + public: false + factory: [ "@api.operation_factory", "createCollectionOperation" ] + arguments: + - "@resource.system_preference" # Resource + - [ "GET" ] # Methods + - "/system_preferences" # Path + - "partkeepr.system_preference.get_preferences" # Controller + - "PartKeeprSystemPreferenceGet" + + resource.system_preference.item_operation.set_preference: + class: "Dunglas\ApiBundle\Api\Operation\Operation" + public: false + factory: [ "@api.operation_factory", "createCollectionOperation" ] + arguments: + - "@resource.system_preference" # Resource + - [ "POST", "PUT" ] # Methods + - "/system_preferences" # Path + - "partkeepr.system_preference.set_preference" # Controller + - "PartKeeprSystemPreferenceSet" + + resource.system_preference.item_operation.delete_preference: + class: "Dunglas\ApiBundle\Api\Operation\Operation" + public: false + factory: [ "@api.operation_factory", "createItemOperation" ] + arguments: + - "@resource.system_preference" # Resource + - [ "DELETE" ] # Methods + - "/system_preferences" # Path + - "partkeepr.system_preference.delete_preference" # Controller + - "PartKeeprSystemPreferenceDelete" + + resource.system_preference: + parent: "api.resource" + arguments: [ "PartKeepr\\SystemPreferenceBundle\\Entity\\SystemPreference" ] + tags: [ { name: "api.resource" } ] + calls: + - method: "initNormalizationContext" + arguments: [ { groups: [ "default" ] } ] + - method: "initCollectionOperations" + arguments: [ [ "@resource.system_preference.item_operation.get_preferences" ] ] + - method: "initItemOperations" + arguments: [ [ "@resource.system_preference.item_operation.set_preference", "@resource.system_preference.item_operation.delete_preference" ] ] + - method: "initDenormalizationContext" + arguments: + - { groups: [ "default" ] }+ \ No newline at end of file diff --git a/composer.lock b/composer.lock @@ -1100,7 +1100,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/migrations/zipball/0074c9416fd8782273b8d390895c6d603b59ae15", + "url": "https://api.github.com/repos/doctrine/migrations/zipball/7ab492c6a65ebe7c0f4665bf96320bef4fb31b70", "reference": "7ab492c6a65ebe7c0f4665bf96320bef4fb31b70", "shasum": "" }, @@ -1240,12 +1240,12 @@ "version": "dev-master", "source": { "type": "git", - "url": "https://github.com/dunglas/DunglasApiBundle.git", + "url": "https://github.com/api-platform/core.git", "reference": "b30de689f94410c7dc0e449f2ecc15cfa8e70f54" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dunglas/DunglasApiBundle/zipball/bb72d0569aaf51420c1b8cfc5b653fa7053ffdfb", + "url": "https://api.github.com/repos/api-platform/core/zipball/b30de689f94410c7dc0e449f2ecc15cfa8e70f54", "reference": "b30de689f94410c7dc0e449f2ecc15cfa8e70f54", "shasum": "" }, @@ -1628,7 +1628,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfSymfony/FOSUserBundle/zipball/e770bfa2fd0fc665f55cd7cfeb34bddeffb892f4", + "url": "https://api.github.com/repos/FriendsOfSymfony/FOSUserBundle/zipball/d5b28c367d393f9d9fbc48c4138b2a74d51c0c83", "reference": "d5b28c367d393f9d9fbc48c4138b2a74d51c0c83", "shasum": "" }, @@ -1975,7 +1975,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/JMSTranslationBundle/zipball/c97c57151ce0283d89a1bea8dbdb15b222052135", + "url": "https://api.github.com/repos/schmittjoh/JMSTranslationBundle/zipball/8eff56746b73762dfe06414faf0fb609bfe51754", "reference": "8eff56746b73762dfe06414faf0fb609bfe51754", "shasum": "" }, @@ -2430,7 +2430,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nelmio/NelmioApiDocBundle/zipball/07545629aa99441cfec1c18619050a346ea273f9", + "url": "https://api.github.com/repos/nelmio/NelmioApiDocBundle/zipball/9af37448fa2f82856d068205afa96e9874527672", "reference": "9af37448fa2f82856d068205afa96e9874527672", "shasum": "" }, @@ -2505,12 +2505,12 @@ "source": { "type": "git", "url": "https://github.com/partkeepr/sprite-generator.git", - "reference": "5e93829623d1d685b3f4228097534c9aa3a6af5a" + "reference": "f43c6c350ef340ed37c237d64855103f1676001f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/partkeepr/sprite-generator/zipball/5e93829623d1d685b3f4228097534c9aa3a6af5a", - "reference": "5e93829623d1d685b3f4228097534c9aa3a6af5a", + "url": "https://api.github.com/repos/partkeepr/sprite-generator/zipball/f43c6c350ef340ed37c237d64855103f1676001f", + "reference": "f43c6c350ef340ed37c237d64855103f1676001f", "shasum": "" }, "require": { @@ -2541,7 +2541,7 @@ "support": { "source": "https://github.com/partkeepr/sprite-generator/tree/min-image-fix" }, - "time": "2015-11-25 17:32:07" + "time": "2016-08-01 15:59:08" }, { "name": "nikic/php-parser", diff --git a/src/PartKeepr/DoctrineReflectionBundle/Filter/AdvancedSearchFilter.php b/src/PartKeepr/DoctrineReflectionBundle/Filter/AdvancedSearchFilter.php @@ -91,26 +91,26 @@ class AdvancedSearchFilter extends AbstractFilter foreach ($filters as $filter) { /** - * @var $filter Filter + * @var Filter $filter */ if (isset($fieldNames[$filter->getProperty()]) && $filter->getAssociation() === null) { if ($filter->hasSubFilters()) { - $subFilterExpressions = []; - - foreach ($filter->getSubFilters() as $subFilter) { - /** - * @var $subFilter Filter - */ - if ($subFilter->getAssociation() !== null) { - $this->addJoins($queryBuilder, $subFilter); - } + $subFilterExpressions = []; - $subFilterExpressions[] = $this->getFilterExpression($queryBuilder, $subFilter); - } + foreach ($filter->getSubFilters() as $subFilter) { + /** + * @var Filter $subFilter + */ + if ($subFilter->getAssociation() !== null) { + $this->addJoins($queryBuilder, $subFilter); + } - $expressions = call_user_func_array(array($queryBuilder->expr(), "orX"), $subFilterExpressions); - $queryBuilder->andWhere($expressions); - } else { + $subFilterExpressions[] = $this->getFilterExpression($queryBuilder, $subFilter); + } + + $expressions = call_user_func_array([$queryBuilder->expr(), "orX"], $subFilterExpressions); + $queryBuilder->andWhere($expressions); + } else { $queryBuilder->andWhere( $this->getFilterExpression($queryBuilder, $filter) ); @@ -129,7 +129,7 @@ class AdvancedSearchFilter extends AbstractFilter foreach ($filter->getSubFilters() as $subFilter) { /** - * @var $subFilter Filter + * @var Filter $subFilter */ if ($subFilter->getAssociation() !== null) { $this->addJoins($queryBuilder, $subFilter); @@ -138,7 +138,7 @@ class AdvancedSearchFilter extends AbstractFilter $subFilterExpressions[] = $this->getFilterExpression($queryBuilder, $subFilter); } - $expressions = call_user_func_array(array($queryBuilder->expr(), "orX"), $subFilterExpressions); + $expressions = call_user_func_array([$queryBuilder->expr(), "orX"], $subFilterExpressions); $queryBuilder->andWhere($expressions); } else { $queryBuilder->andWhere( @@ -151,7 +151,7 @@ class AdvancedSearchFilter extends AbstractFilter foreach ($sorters as $sorter) { /** - * @var $sorter Sorter + * @var Sorter $sorter */ if ($sorter->getAssociation() !== null) { // Pull in associations @@ -287,7 +287,7 @@ class AdvancedSearchFilter extends AbstractFilter return $queryBuilder->expr()->like($alias, $paramName); break; default: - throw new \Exception('Unknown operator '.$filter->getOperator()); + throw new \Exception('Unknown operator ' . $filter->getOperator()); } } } @@ -457,7 +457,7 @@ class AdvancedSearchFilter extends AbstractFilter break; case 'ASC': default: - $sorter->setDirection("ASC"); + $sorter->setDirection("ASC"); break; } } else { diff --git a/src/PartKeepr/DoctrineReflectionBundle/Filter/AssociationPropertyInterface.php b/src/PartKeepr/DoctrineReflectionBundle/Filter/AssociationPropertyInterface.php @@ -1,6 +1,6 @@ <?php -namespace PartKeepr\DoctrineReflectionBundle\Filter; +namespace PartKeepr\DoctrineReflectionBundle\Filter; interface AssociationPropertyInterface { diff --git a/src/PartKeepr/DoctrineReflectionBundle/Filter/AssociationPropertyTrait.php b/src/PartKeepr/DoctrineReflectionBundle/Filter/AssociationPropertyTrait.php @@ -1,6 +1,6 @@ <?php -namespace PartKeepr\DoctrineReflectionBundle\Filter; +namespace PartKeepr\DoctrineReflectionBundle\Filter; trait AssociationPropertyTrait { @@ -44,6 +44,4 @@ trait AssociationPropertyTrait { $this->association = $association; } - - } \ No newline at end of file diff --git a/src/PartKeepr/DoctrineReflectionBundle/Filter/Filter.php b/src/PartKeepr/DoctrineReflectionBundle/Filter/Filter.php @@ -6,8 +6,9 @@ class Filter implements AssociationPropertyInterface { use AssociationPropertyTrait; - const TYPE_AND = "and"; - const TYPE_OR = "or"; + const TYPE_AND = 'and'; + const TYPE_OR = 'or'; + const OPERATOR_LESS_THAN = '<'; const OPERATOR_GREATER_THAN = '>'; const OPERATOR_EQUALS = '='; @@ -30,7 +31,7 @@ class Filter implements AssociationPropertyInterface const TYPES = [ self::TYPE_AND, - self::TYPE_OR + self::TYPE_OR, ]; /** @@ -47,21 +48,17 @@ class Filter implements AssociationPropertyInterface */ private $value; /** - * Subfilters + * SubFilters. * @var array */ private $subFilters; - public function __construct($type = self::TYPE_AND) { $this->setType($type); } - - - /** * @return string */ @@ -72,6 +69,7 @@ class Filter implements AssociationPropertyInterface /** * @param string $type + * * @throws \Exception */ public function setType($type) @@ -133,15 +131,9 @@ class Filter implements AssociationPropertyInterface $this->subFilters = $subFilters; } - public function hasSubFilters () { - return count($this->subFilters) > 0; - } - - - public function validate() + public function hasSubFilters() { - + return count($this->subFilters) > 0; } - } \ No newline at end of file diff --git a/src/PartKeepr/DoctrineReflectionBundle/Filter/PropertyFilter.php b/src/PartKeepr/DoctrineReflectionBundle/Filter/PropertyFilter.php @@ -1,15 +0,0 @@ -<?php -/** - * Created by PhpStorm. - * User: felicitus - * Date: 7/30/16 - * Time: 5:20 PM - */ - -namespace PartKeepr\DoctrineReflectionBundle\Filter; - - -class PropertyFilter -{ - -}- \ No newline at end of file diff --git a/src/PartKeepr/DoctrineReflectionBundle/Filter/Sorter.php b/src/PartKeepr/DoctrineReflectionBundle/Filter/Sorter.php @@ -1,7 +1,9 @@ <?php + namespace PartKeepr\DoctrineReflectionBundle\Filter; -class Sorter implements AssociationPropertyInterface { +class Sorter implements AssociationPropertyInterface +{ use AssociationPropertyTrait; diff --git a/src/PartKeepr/FrontendBundle/Resources/public/js/Components/Editor/EditorGrid.js b/src/PartKeepr/FrontendBundle/Resources/public/js/Components/Editor/EditorGrid.js @@ -72,6 +72,26 @@ Ext.define('PartKeepr.EditorGrid', { editItemAsObject: false, /** + * @cfg {String} Specifies the system property which defines all fields to be searched + */ + searchFieldSystemPreference: null, + + /** + * @cfg {Array} Specifies the default fields to be searched + */ + searchFieldSystemPreferenceDefaults: [], + + /** + * @cfg {String} Specifies the system property which defines if the search terms should be splitted + */ + splitSearchTermSystemPreference: null, + + /** + * @cfg {String} Specifies the default for search term splitting + */ + splitSearchTermSystemPreferenceDefaults: true, + + /** * @cfg {String} The title property */ titleProperty: null, @@ -83,7 +103,7 @@ Ext.define('PartKeepr.EditorGrid', { /** * @event itemSelect * Fires if a record was selected within the grid. - * @param {Object} record The selected record + * @param {Object} Ext.data.Record The selected record */ initComponent: function () { @@ -137,15 +157,13 @@ Ext.define('PartKeepr.EditorGrid', { var targetField = this.titleProperty; - if (this.searchField) { - targetField = this.searchField; - } - - console.log(targetField); - this.searchField = Ext.create("PartKeepr.form.field.SearchField", { store: this.store, - targetField: targetField + targetField: targetField, + searchFieldSystemPreference: this.searchFieldSystemPreference, + searchFieldSystemPreferenceDefaults: this.searchFieldSystemPreferenceDefaults, + splitSearchTermSystemPreference: this.splitSearchTermSystemPreference, + splitSearchTermSystemPreferenceDefaults: this.splitSearchTermSystemPreferenceDefaults }); var topToolbarItems = []; @@ -200,9 +218,6 @@ Ext.define('PartKeepr.EditorGrid', { * Re-calculates and re-assigns the page size for the assigned store. * * Automatically reloads the store. - * - * @param none - * @return nothing */ reassignPageSize: function () { @@ -237,7 +252,7 @@ Ext.define('PartKeepr.EditorGrid', { this.bottomToolbar.setStore(store); }, - syncChanges: function (record) + syncChanges: function () { // Simply reload the store for now this.store.load(); @@ -245,7 +260,7 @@ Ext.define('PartKeepr.EditorGrid', { /** * Called when an item was selected. Enables/disables the delete button. */ - _updateDeleteButton: function (selectionModel, record) + _updateDeleteButton: function () { /* Right now, we support delete on a single record only */ if (this.getSelectionModel().getCount() == 1) { diff --git a/src/PartKeepr/FrontendBundle/Resources/public/js/Components/MenuBar.js b/src/PartKeepr/FrontendBundle/Resources/public/js/Components/MenuBar.js @@ -10,7 +10,7 @@ Ext.define('PartKeepr.MenuBar', { var item = menuPath.shift(); if (item === undefined) { - var newItem = { text: target.title, iconCls: target.iconCls, target: target }; + var newItem = {text: target.title, iconCls: target.iconCls, target: target}; root.menu.push(newItem); return root; @@ -18,15 +18,15 @@ Ext.define('PartKeepr.MenuBar', { var foundItem = false; - for (var i=0;i<root.menu.length;i++) { - if (root.menu[i].text == item.text) { - Ext.applyIf(root.menu[i], item); - foundItem = i; - } + for (var i = 0; i < root.menu.length; i++) { + if (root.menu[i].text == item.text) { + Ext.applyIf(root.menu[i], item); + foundItem = i; + } } if (foundItem === false) { - var newItem = { menu: []}; + var newItem = {menu: []}; Ext.applyIf(newItem, item); @@ -39,8 +39,7 @@ Ext.define('PartKeepr.MenuBar', { return root; }, - initComponent: function () - { + initComponent: function () { var target, menus, menuItemIterator, menuPathIterator; this.ui = "mainmenu"; @@ -48,6 +47,7 @@ Ext.define('PartKeepr.MenuBar', { var menuItems = [ // System Menu "PartKeepr.UserPreferencePanel", + "PartKeepr.Components.SystemPreferences.Panel", "PartKeepr.Actions.LogoutAction", // Edit Menu @@ -70,15 +70,15 @@ Ext.define('PartKeepr.MenuBar', { ]; - for (menuItemIterator=0;menuItemIterator < menuItems.length;menuItemIterator++) { + for (menuItemIterator = 0; menuItemIterator < menuItems.length; menuItemIterator++) { target = Ext.ClassManager.get(menuItems[menuItemIterator]); if (!target) { - console.log("Error: "+menuItems[menuItemIterator] + " not found!"); + console.log("Error: " + menuItems[menuItemIterator] + " not found!"); } if (!target.menuPath) { - console.log("Error: "+menuItems[menuItemIterator] + " has no menuPath defined!"); + console.log("Error: " + menuItems[menuItemIterator] + " has no menuPath defined!"); } this.createMenu(target, target.menuPath, this.menu); } diff --git a/src/PartKeepr/FrontendBundle/Resources/public/js/Components/Part/PartsGrid.js b/src/PartKeepr/FrontendBundle/Resources/public/js/Components/Part/PartsGrid.js @@ -58,7 +58,11 @@ Ext.define('PartKeepr.PartsGrid', { autoScroll: false, invalidateScrollerOnRefresh: true, titleProperty: 'name', - searchField: ["name", "description", "comment", "internalPartNumber"], + searchFieldSystemPreference: "partkeepr.part.search.field", + searchFieldSystemPreferenceDefaults: ["name", "description", "comment", "internalPartNumber"], + splitSearchTermSystemPreference: "partkeepr.part.search.split", + splitSearchTermSystemPreferenceDefaults: true, + initComponent: function () { diff --git a/src/PartKeepr/FrontendBundle/Resources/public/js/Components/SystemPreferences/Panel.js b/src/PartKeepr/FrontendBundle/Resources/public/js/Components/SystemPreferences/Panel.js @@ -0,0 +1,75 @@ +Ext.define('PartKeepr.Components.SystemPreferences.Panel', { + extend: 'Ext.panel.Panel', + title: i18n("System Preferences"), + layout: 'border', + + initComponent: function () { + var settings = [ + "PartKeepr.Components.SystemPreferences.Preferences.FulltextSearch" + ]; + + var settingItems = [], item; + + settingItems.push(new Ext.create("Ext.panel.Panel", { + layout: "center", + items: { + width: "100%", + border: false, + bodyStyle: "text-align: center;", + html: "<h1>" + i18n("Select an item to edit") + "</h1>" + } + })); + + for (var i = 0; i < settings; i++) { + item = Ext.create(settings[i]); + settingItems.push(item) + } + + this.navigation = Ext.create("PartKeepr.Components.SystemPreferences.Tree", + { + menuItems: settings, + region: "west", + width: 200 + }); + + this.navigation.on("itemclick", function (record, item) { + if (typeof item.data.target === "function") { + this.openSettingsItem(item.data.target["$className"]); + } + }, this); + + this.cards = Ext.create("Ext.panel.Panel", { + region: 'center', + layout: 'card', + items: settingItems + }); + + this.items = [ + this.navigation, + this.cards + ]; + + this.callParent(); + }, + openSettingsItem: function (target) { + targetClass = Ext.ClassManager.get(target); + + var config = { + title: targetClass.title, + closable: targetClass.closable, + iconCls: targetClass.iconCls + }; + + var j = Ext.create(target, config); + + this.cards.items.add(j); + this.cards.setActiveItem(j); + }, + statics: { + iconCls: 'fugue-icon gear', + title: i18n('System Preferences'), + closable: true, + menuPath: [{text: i18n("System")}] + } + +});+ \ No newline at end of file diff --git a/src/PartKeepr/FrontendBundle/Resources/public/js/Components/SystemPreferences/PreferenceEditor.js b/src/PartKeepr/FrontendBundle/Resources/public/js/Components/SystemPreferences/PreferenceEditor.js @@ -0,0 +1,53 @@ +Ext.define('PartKeepr.Components.SystemPreferences.PreferenceEditor', { + extend: 'Ext.form.Panel', + trackResetOnLoad: true, + bodyPadding: 10, + saveText: i18n("Save"), + cancelText: i18n("Cancel"), + layout: 'anchor', + change: false, + autoScroll: true, + defaults: { + anchor: '100%', + labelWidth: 150 + }, + enableButtons: true, + titleProperty: 'name', + + initComponent: function () { + if (this.enableButtons) { + this.saveButton = Ext.create("Ext.button.Button", { + text: this.saveText, + iconCls: 'fugue-icon disk', + handler: Ext.bind(this.onSave, this) + }); + + this.cancelButton = Ext.create("Ext.button.Button", { + text: this.cancelText, + iconCls: 'web-icon cancel', + handler: Ext.bind(this.onCancelEdit, this) + }); + + this.bottomToolbar = Ext.create("Ext.toolbar.Toolbar", { + enableOverflow: true, + margin: '10px', + defaults: {minWidth: 100}, + dock: 'bottom', + ui: 'footer', + items: [this.saveButton, this.cancelButton] + }); + + Ext.apply(this, { + dockedItems: [this.bottomToolbar] + }); + } + + this.callParent(); + }, + onCancelEdit: function () { + this.fireEvent("editorClose", this); + }, + onSave: function () { + console.log("You need to override PreferenceEditor::onSave") + } +}); diff --git a/src/PartKeepr/FrontendBundle/Resources/public/js/Components/SystemPreferences/Preferences/FulltextSearch.js b/src/PartKeepr/FrontendBundle/Resources/public/js/Components/SystemPreferences/Preferences/FulltextSearch.js @@ -0,0 +1,82 @@ +Ext.define('PartKeepr.Components.SystemPreferences.Preferences.FulltextSearch', { + extend: 'PartKeepr.Components.SystemPreferences.PreferenceEditor', + scrollable: true, + layout: 'anchor', + border: false, + defaults: { + anchor: '100%' + }, + initComponent: function () { + + this.fieldSelector = Ext.create("PartKeepr.Components.Widgets.FieldSelector", { + height: 300, + sourceModel: PartKeepr.PartBundle.Entity.Part, + initiallyChecked: PartKeepr.getApplication().getSystemPreference("partkeepr.part.search.fields", ["name", "description", "comment", "internalPartNumber"]) + }); + + this.items = [ + { + xtype: 'fieldcontainer', + fieldLabel: i18n("Search Mode"), + defaultType: 'radiofield', + defaults: { + flex: 1 + }, + layout: 'vbox', + items: [ + { + boxLabel: i18n("Use entered text as-is"), + name: 'splitMode', + inputValue: 'full', + id: 'searchModeFull' + }, { + boxLabel: i18n("Separate search terms"), + name: 'splitMode', + inputValue: 'split', + id: 'searchModeSplit' + } + ] + }, + { + xtype: "fieldcontainer", + fieldLabel: i18n("Search Fields"), + items: [{ + style: "padding-top: 4px; padding-bottom: 5px;", + html: i18n("Select all fields which are searched when entering a search term in the upper-right search field within the part manager"), + border: false + }, this.fieldSelector] + } + ]; + + this.callParent(arguments); + + if (PartKeepr.getApplication().getSystemPreference("partkeepr.part.search.split", true)) { + this.down("#searchModeFull").setValue(false); + this.down("#searchModeSplit").setValue(true); + } else { + this.down("#searchModeFull").setValue(true); + this.down("#searchModeSplit").setValue(false); + } + }, + onSave: function () { + var selection = this.fieldSelector.getChecked(); + var fields = []; + + for (var i = 0; i < selection.length; i++) { + fields.push(selection[i].data.data); + } + + PartKeepr.getApplication().setSystemPreference("partkeepr.part.search.fields", fields); + + if (this.down("#searchModeFull").getValue()) { + PartKeepr.getApplication().setSystemPreference("partkeepr.part.search.split", false); + } else { + PartKeepr.getApplication().setSystemPreference("partkeepr.part.search.split", true); + } + }, + statics: { + iconCls: 'fugue-icon magnifier-medium', + title: i18n('Fulltext Search'), + menuPath: [{text: i18n("Search")}] + } +}); diff --git a/src/PartKeepr/FrontendBundle/Resources/public/js/Components/SystemPreferences/Tree.js b/src/PartKeepr/FrontendBundle/Resources/public/js/Components/SystemPreferences/Tree.js @@ -0,0 +1,67 @@ +Ext.define('PartKeepr.Components.SystemPreferences.Tree', { + extend: 'Ext.tree.Panel', + width: 400, + rootVisible: false, + initComponent: function (config) { + var menu = { + root: { + expanded: true, + children: [] + } + }; + + var target, menuItemIterator; + + for (menuItemIterator = 0; menuItemIterator < this.menuItems.length; menuItemIterator++) { + target = Ext.ClassManager.get(this.menuItems[menuItemIterator]); + + if (!target) { + console.log("Error: " + this.menuItems[menuItemIterator] + " not found!"); + } + + if (!target.menuPath) { + console.log("Error: " + this.menuItems[menuItemIterator] + " has no menuPath defined!"); + } + + this.createMenu(target, Ext.clone(target.menuPath), menu.root); + } + + this.store = Ext.create('Ext.data.TreeStore', menu); + + this.callParent(this, config); + }, + + createMenu: function (target, menuPath, root) { + var item = menuPath.shift(); + var newItem; + + if (item === undefined) { + newItem = {text: target.title, iconCls: target.iconCls, expanded: true, target: target, leaf: true}; + + root.children.push(newItem); + return root; + } + + var foundItem = false; + + for (var i = 0; i < root.children.length; i++) { + if (root.children[i].text == item.text) { + Ext.applyIf(root.children[i], item); + foundItem = i; + } + } + + if (foundItem === false) { + newItem = {children: [], expanded: true}; + + Ext.applyIf(newItem, item); + + var data = this.createMenu(target, menuPath, newItem); + root.children.push(data); + } else { + this.createMenu(target, menuPath, root.children[foundItem]); + } + + return root; + } +});+ \ No newline at end of file diff --git a/src/PartKeepr/FrontendBundle/Resources/public/js/Components/Widgets/FieldSelector.js b/src/PartKeepr/FrontendBundle/Resources/public/js/Components/Widgets/FieldSelector.js @@ -0,0 +1,78 @@ +Ext.define('PartKeepr.Components.Widgets.FieldSelector', { + extend: 'Ext.tree.Panel', + store: { + folderSort: true, + sorters: [ + { + property: 'text', + direction: 'ASC' + } + ] + }, + useArrows: true, + model: null, + selModel: { + mode: 'MULTI' + }, + initiallyChecked: [], + + /** + * @var {Array} Contains the models already in the field tree + */ + visitedModels: [], + + initComponent: function () { + this.callParent(arguments); + + var rootNode = this.getRootNode(); + rootNode.set("text", this.sourceModel.getName()); + this.treeMaker(rootNode, this.sourceModel, ""); + rootNode.expand(); + }, + /** + * Builds the field tree recursively. Handles infinite recursions (e.g. in trees). + * + * @param {Ext.data.NodeInterface} The current node + * @param {Ext.data.Model} The model + * @param {String} The prefix. Omit if first called + */ + treeMaker: function (node, model, prefix) + { + var fields = model.getFields(); + var checked; + + this.visitedModels.push(model.getName()); + for (var i = 0; i < fields.length; i++) { + + if (fields[i]["$reference"] === undefined) { + checked = false; + + if (Ext.Array.contains(this.initiallyChecked, prefix + fields[i].name)) { + checked = true; + } + + node.appendChild({ + text: fields[i].name, + leaf: true, + checked: checked, + data: prefix + fields[i].name + }); + } else { + for (var j = 0; j < this.visitedModels.length; j++) { + if (this.visitedModels[j] === fields[i].reference.cls.getName()) { + return; + } + } + + var childNode = node.appendChild({ + text: fields[i].name, + expanded: true, + leaf: false + }); + + this.treeMaker(childNode, fields[i].reference.cls, prefix + fields[i].name + "."); + } + + } + } +}); diff --git a/src/PartKeepr/FrontendBundle/Resources/public/js/Data/store/SystemPreferenceStore.js b/src/PartKeepr/FrontendBundle/Resources/public/js/Data/store/SystemPreferenceStore.js @@ -0,0 +1,20 @@ +Ext.define('PartKeepr.data.store.SystemPreferenceStore', { + extend: 'Ext.data.Store', + + /** + * The store ID to use + */ + storeId: 'SystemPreferenceStore', + + /** + * Automatically load the store + */ + autoLoad: true, + + /** + * The model to use + */ + model: "PartKeepr.SystemPreferenceBundle.Entity.SystemPreference", + + pageSize: 99999999 +}); diff --git a/src/PartKeepr/FrontendBundle/Resources/public/js/PartKeepr.js b/src/PartKeepr/FrontendBundle/Resources/public/js/PartKeepr.js @@ -10,8 +10,7 @@ Ext.application({ }, - launch: function () - { + launch: function () { Ext.setGlyphFontFamily('FontAwesome'); Ext.get("loading").hide(); Ext.setLocale('en_US'); @@ -27,7 +26,7 @@ Ext.application({ var authenticationProvider = Ext.create(window.parameters.authentication_provider); PartKeepr.Auth.AuthenticationProvider.setAuthenticationProvider(authenticationProvider); - this.control ({ + this.control({ 'MenuBar menuitem': { click: this.onAppMenuClick, scope: this @@ -70,26 +69,22 @@ Ext.application({ j.show(); } }, - getParameter: function (parameter) - { + getParameter: function (parameter) { if (window.parameters[parameter] !== undefined) { return window.parameters[parameter]; } }, - getLoginManager: function () - { + getLoginManager: function () { return this.loginManager; }, - getPartManager: function () - { + getPartManager: function () { return this.partManager; }, /** * Handles the login function. Initializes the part manager window, * enables the menu bar and creates the stores+loads them. */ - onLogin: function () - { + onLogin: function () { this.createGlobalStores(); var initialUserPreferences = Ext.decode(this.getLoginManager().getUser().get("initialUserPreferences")); @@ -120,8 +115,7 @@ Ext.application({ this.getStatusbar().setConnected(); }, - onLogout: function () - { + onLogout: function () { this.menuBar.disable(); this.centerPanel.removeAll(true); this.getStatusbar().setDisconnected(); @@ -135,8 +129,7 @@ Ext.application({ * @param none * @return nothing */ - recreatePartManager: function () - { + recreatePartManager: function () { this.centerPanel.remove(this.partManager); this.getPartManager().destroy(); @@ -146,8 +139,7 @@ Ext.application({ * Creates the part manager. While this is usually only done after login, it can also happen when the user changes * the "compact" preference. */ - createPartManager: function () - { + createPartManager: function () { this.partManager = Ext.create("PartKeepr.PartManager", { title: i18n("Part Manager"), compactLayout: PartKeepr.getApplication().getUserPreference("partkeepr.partmanager.compactlayout", false), @@ -160,8 +152,7 @@ Ext.application({ /** * Sets the initial user preferences, which are applied into the userPreferenceStore after login. */ - setInitialUserPreferences: function (obj) - { + setInitialUserPreferences: function (obj) { PartKeepr.initialUserPreferences = obj; }, /** @@ -170,12 +161,10 @@ Ext.application({ * This method checks if the user has disabled tips, and if so, this method * avoids showing the window. */ - displayTipOfTheDayWindow: function () - { + displayTipOfTheDayWindow: function () { if (!Ext.data.StoreManager.lookup('TipOfTheDayStore') || !Ext.data.StoreManager.lookup( 'TipOfTheDayStore').isLoaded() || !Ext.data.StoreManager.lookup( - 'TipOfTheDayHistoryStore') || !Ext.data.StoreManager.lookup('TipOfTheDayHistoryStore').isLoaded() || - !this.getUserPreferenceStore().isLoaded() + 'TipOfTheDayHistoryStore') || !Ext.data.StoreManager.lookup('TipOfTheDayHistoryStore').isLoaded() || !this.getUserPreferenceStore().isLoaded() ) { this.displayTipWindowTask.delay(100); return; @@ -192,8 +181,7 @@ Ext.application({ /** * Displays a message-of-the-day */ - displayMOTD: function () - { + displayMOTD: function () { Ext.MessageBox.alert(i18n("Message of the day"), window.parameters.motd); }, /** @@ -202,8 +190,7 @@ Ext.application({ * @param none * @return nothing */ - doSystemStatusCheck: function () - { + doSystemStatusCheck: function () { var call = new PartKeepr.ServiceCall("api", "system_status"); call.setHandler(Ext.bind(this.onSystemStatusCheck, this)); call.doCall(); @@ -212,8 +199,7 @@ Ext.application({ * Handler for the schema check * @param data The data returned from the server */ - onSystemStatusCheck: function (data) - { + onSystemStatusCheck: function (data) { if (data.schemaStatus !== "complete") { alert(i18n("Your database schema is not up-to-date! Please re-run setup immediately!")); } @@ -230,8 +216,7 @@ Ext.application({ * @param none * @return nothing */ - doUnacknowledgedNoticesCheck: function () - { + doUnacknowledgedNoticesCheck: function () { this.systemNoticeStore.load({ scope: this, callback: this.onUnacknowledgedNoticesCheck @@ -241,16 +226,14 @@ Ext.application({ * Handler for the unacknowledged system notices check * @param data The data returned from the server */ - onUnacknowledgedNoticesCheck: function () - { + onUnacknowledgedNoticesCheck: function () { if (this.systemNoticeStore.count() > 0) { this.statusBar.systemNoticeButton.show(); } else { this.statusBar.systemNoticeButton.hide(); } }, - createGlobalStores: function () - { + createGlobalStores: function () { this.footprintStore = Ext.create("Ext.data.Store", { model: 'PartKeepr.FootprintBundle.Entity.Footprint', @@ -306,23 +289,75 @@ Ext.application({ autoLoad: false }); + this.systemPreferenceStore = Ext.create("PartKeepr.data.store.SystemPreferenceStore", + { + model: 'PartKeepr.SystemPreferenceBundle.Entity.SystemPreference', + autoLoad: true + }); + this.tipOfTheDayStore = Ext.create("PartKeepr.data.store.TipOfTheDayStore"); this.tipOfTheDayHistoryStore = Ext.create("PartKeepr.data.store.TipOfTheDayHistoryStore"); this.systemNoticeStore = Ext.create("PartKeepr.data.store.SystemNoticeStore"); }, - storeLoaded: function (store) - { + storeLoaded: function (store) { store._loaded = true; }, - setAdmin: function (admin) - { + setAdmin: function (admin) { this.admin = admin; }, - isAdmin: function () - { + isAdmin: function () { return this.admin; }, + getSystemPreferenceStore: function () { + return this.systemPreferenceStore; + }, + /** + * Queries for a specific system preference. Returns either the value or a default value if + * the preference was not found. + * @param key The key to query + * @param defaultValue A default value to return (optional) + * @returns the key value, or defaultValue if preference key was not found + */ + getSystemPreference: function (key, defaultValue) { + var record = this.systemPreferenceStore.findRecord("preferenceKey", key); + + if (record) { + var value = record.get("preferenceValue"); + var decodedValue = Ext.decode(value, true); + + if (decodedValue === null) { + return value; + } else { + return decodedValue; + } + } else { + return (typeof defaultValue == "undefined") ? null : defaultValue; + } + }, + /** + * Sets a specific system preference. Directly commits the change to the server. + * + * @param key The key to set + * @param value The value to set + */ + setSystemPreference: function (key, value) { + var record = this.systemPreferenceStore.findRecord("preferenceKey", key); + value = Ext.encode(value); + + if (record) { + if (record.get("preferenceValue") != value) { + record.set("preferenceValue", value); + record.save(); + } + } else { + var j = new PartKeepr.SystemPreferenceBundle.Entity.SystemPreference(); + j.set("preferenceKey", key); + j.set("preferenceValue", value); + j.save(); + this.systemPreferenceStore.add(j); + } + }, /** * Queries for a specific user preference. Returns either the value or a default value if * the preference was not found. @@ -330,8 +365,7 @@ Ext.application({ * @param defaultValue A default value to return (optional) * @returns the key value, or defaultValue if preference key was not found */ - getUserPreference: function (key, defaultValue) - { + getUserPreference: function (key, defaultValue) { var record = this.userPreferenceStore.findRecord("preferenceKey", key); if (record) { @@ -353,8 +387,7 @@ Ext.application({ * @param key The key to set * @param value The value to set */ - setUserPreference: function (key, value) - { + setUserPreference: function (key, value) { var record = this.userPreferenceStore.findRecord("preferenceKey", key); value = Ext.encode(value); @@ -371,40 +404,31 @@ Ext.application({ this.userPreferenceStore.add(j); } }, - getUserPreferenceStore: function () - { + getUserPreferenceStore: function () { return this.userPreferenceStore; }, - getUnitStore: function () - { + getUnitStore: function () { return this.unitStore; }, - getPartUnitStore: function () - { + getPartUnitStore: function () { return this.partUnitStore; }, - getFootprintStore: function () - { + getFootprintStore: function () { return this.footprintStore; }, - getManufacturerStore: function () - { + getManufacturerStore: function () { return this.manufacturerStore; }, - getDistributorStore: function () - { + getDistributorStore: function () { return this.distributorStore; }, - getDefaultPartUnit: function () - { + getDefaultPartUnit: function () { return this.partUnitStore.findRecord("default", true); }, - getUserStore: function () - { + getUserStore: function () { return this.userStore; }, - getSiPrefixStore: function () - { + getSiPrefixStore: function () { return this.siPrefixStore; }, /** @@ -415,8 +439,7 @@ Ext.application({ * Wikipedia Entry for the "Micro" Si Prefix: http://en.wikipedia.org/wiki/Micro- * */ - convertMicroToMu: function (value) - { + convertMicroToMu: function (value) { /** * Since the Si-Prefix for "micro" is μ, but keyboard have "µ" on it * (note: both chars might look identical, depending on your font), we need @@ -428,8 +451,7 @@ Ext.application({ /** * Creates the main view of PartKeepr. */ - createLayout: function () - { + createLayout: function () { this.statusBar = Ext.create("PartKeepr.Statusbar"); @@ -465,12 +487,10 @@ Ext.application({ }); }, - addItem: function (item) - { + addItem: function (item) { this.centerPanel.add(item); }, - createMessageLog: function () - { + createMessageLog: function () { return Ext.create("PartKeepr.MessageLog", { height: 200, hidden: true, @@ -481,8 +501,7 @@ Ext.application({ region: 'south', listeners: { beforecollapse: Ext.bind( - function (obj) - { + function (obj) { this.hideMessageLog(); return false; }, @@ -490,12 +509,10 @@ Ext.application({ } }); }, - log: function (message) - { + log: function (message) { this.logMessage(message, "none"); }, - logMessage: function (message, severity) - { + logMessage: function (message, severity) { if (message != i18n("Ready.")) { var r = Ext.ModelManager.create({ message: message, @@ -506,16 +523,13 @@ Ext.application({ this.messageLog.getStore().add(r); } }, - hideMessageLog: function () - { + hideMessageLog: function () { this.messageLog.hide(); }, - showMessageLog: function () - { + showMessageLog: function () { this.messageLog.show(); }, - toggleMessageLog: function () - { + toggleMessageLog: function () { if (this.messageLog.isHidden()) { this.showMessageLog(); } else { @@ -523,8 +537,7 @@ Ext.application({ } }, - getStatusbar: function () - { + getStatusbar: function () { return this.statusBar; }, /** @@ -534,8 +547,7 @@ Ext.application({ * * @param {string} username The username to set */ - setUsername: function (username) - { + setUsername: function (username) { this.username = username; this.getStatusbar().setCurrentUser(username); }, @@ -543,12 +555,10 @@ Ext.application({ * Returns the current username * @returns {string} */ - getUsername: function () - { + getUsername: function () { return this.username; }, - formatCurrency: function (value) - { + formatCurrency: function (value) { var format = Ext.util.Format; format.currencyPrecision = PartKeepr.getApplication().getUserPreference( "partkeepr.formatting.currency.numdecimals", 2); @@ -568,14 +578,12 @@ Ext.application({ } }); -PartKeepr.getSession = function () -{ +PartKeepr.getSession = function () { alert("This should not be called."); return "hli2ong0ktnise68p9f5nu6nk1"; }; -PartKeepr.log = function (message) -{ +PartKeepr.log = function (message) { PartKeepr.getApplication().log(message); }; @@ -583,44 +591,38 @@ PartKeepr.log = function (message) * <p>This static method returns the instance of the application.</p> * @return {Object} The application */ -PartKeepr.getApplication = function () -{ +PartKeepr.getApplication = function () { return PartKeepr.application; }; -PartKeepr.getBasePath = function () -{ +PartKeepr.getBasePath = function () { var href = document.getElementsByTagName('base')[0].href; - if(href.substr(-2) === '//') { + if (href.substr(-2) === '//') { return href.substr(0, href.length - 2); } - if(href.substr(-1) === '/') { + if (href.substr(-1) === '/') { return href.substr(0, href.length - 1); } return href; }; -PartKeepr.getImagePath = function () -{ +PartKeepr.getImagePath = function () { return "image.php"; }; -PartKeepr.setMaxUploadSize = function (size) -{ +PartKeepr.setMaxUploadSize = function (size) { PartKeepr.maxUploadSize = size; }; -PartKeepr.getMaxUploadSize = function () -{ +PartKeepr.getMaxUploadSize = function () { return PartKeepr.maxUploadSize; }; -PartKeepr.bytesToSize = function (bytes) -{ +PartKeepr.bytesToSize = function (bytes) { var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; if (bytes === 0) { return '0 Bytes'; @@ -629,18 +631,15 @@ PartKeepr.bytesToSize = function (bytes) return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i]; }; -PartKeepr.setAvailableImageFormats = function (formats) -{ +PartKeepr.setAvailableImageFormats = function (formats) { PartKeepr.imageFormats = formats; }; -PartKeepr.getAvailableImageFormats = function () -{ +PartKeepr.getAvailableImageFormats = function () { return PartKeepr.imageFormats; }; -PartKeepr.serializeRecords = function (records) -{ +PartKeepr.serializeRecords = function (records) { var finalData = []; for (var i = 0; i < records.length; i++) { diff --git a/src/PartKeepr/FrontendBundle/Resources/public/js/form/field/SearchField.js b/src/PartKeepr/FrontendBundle/Resources/public/js/form/field/SearchField.js @@ -31,6 +31,27 @@ Ext.define('PartKeepr.form.field.SearchField', { */ targetField: 'query', + + /** + * @cfg {String} Specifies the system property which defines all fields to be searched + */ + searchFieldSystemPreference: null, + + /** + * @cfg {Array} Specifies the default fields to be searched + */ + searchFieldSystemPreferenceDefaults: [], + + /** + * @cfg {String} Specifies the system property which defines if the search terms should be splitted + */ + splitSearchTermSystemPreference: null, + + /** + * @cfg {String} Specifies the default for search term splitting + */ + splitSearchTermSystemPreferenceDefaults: true, + /** * @var {Ext.util.Filter} The filter set by the search field */ @@ -45,28 +66,6 @@ Ext.define('PartKeepr.form.field.SearchField', { initComponent: function () { this.callParent(arguments); - - if (this.targetField instanceof Array) { - var subFilters = new Array(); - for (var i = 0; i < this.targetField.length; i++) { - subFilters.push(Ext.create("PartKeepr.util.Filter", { - property: this.targetField[i], - value: '', - operator: 'like' - })); - } - - this.filter = Ext.create("PartKeepr.util.Filter", { - type: "OR", - subfilters: subFilters - }); - } else { - this.filter = Ext.create("PartKeepr.util.Filter", { - property: this.targetField, - value: '', - operator: 'like' - }); - } }, /** * Handles special keys used in this field. @@ -97,17 +96,11 @@ Ext.define('PartKeepr.form.field.SearchField', { } me.setValue(''); - if (this.filter.subfilters instanceof Array) { - for (var i=0;i<this.filter.subfilters.length;i++) { - this.filter.subfilters[i].setValue(''); - } - } - this.filter.setValue(''); if (me.hasSearch) { - store.removeFilter(this.filter); + store.getFilters().clear(); store.currentPage = 1; store.load({start: 0}); @@ -122,10 +115,53 @@ Ext.define('PartKeepr.form.field.SearchField', { startSearch: function () { var me = this, store = me.store, - value = me.getValue(), - searchValue = "%" + value + "%"; + searchValue = me.getValue(), + searchTerms = searchValue.split(" "), + splitTerms = true, + i, + j, + subFilters = []; + + if (this.splitSearchTermSystemPreference !== null) { + splitTerms = Boolean(PartKeepr.getApplication().getSystemPreference(this.splitSearchTermSystemPreference, this.splitSearchTermSystemPreferenceDefaults)); + } + + if (this.searchFieldSystemPreference !== null) { + var fields = PartKeepr.getApplication().getSystemPreference(this.searchFieldSystemPreference, this.searchFieldSystemPreferenceDefaults) + + for (i = 0; i < fields.length; i++) { + if (splitTerms === true) { + for (j = 0; j < searchTerms.length; j++) { + subFilters.push(this.createFilter(fields[i], searchTerms[j])); + } + } else { + subFilters.push(this.createFilter(fields[i], searchValue)); + } - if (value.length < 1) { + } + + this.filter = Ext.create("PartKeepr.util.Filter", { + type: "OR", + subfilters: subFilters + }); + } else { + if (splitTerms === true) { + for (j = 0; j < searchTerms.length; j++) { + for (j = 0; j < searchTerms.length; j++) { + subFilters.push(this.createFilter(this.targetField, searchTerms[j])); + } + } + + this.filter = Ext.create("PartKeepr.util.Filter", { + type: "OR", + subfilters: subFilters + }); + } else { + this.filter = this.createFilter(this.targetField, searchValue); + } + } + + if (searchValue.length < 1) { me.resetSearch(); return; } @@ -135,24 +171,22 @@ Ext.define('PartKeepr.form.field.SearchField', { return; } - if (this.filter.getValue() === searchValue) { - return; - } - - if (this.filter.subfilters instanceof Array) { - for (var i=0;i<this.filter.subfilters.length;i++) { - this.filter.subfilters[i].setValue(searchValue); - } - } - this.filter.setValue(searchValue); - store.addFilter(this.filter); + store.getFilters().clear(); + store.setFilters(this.filter); store.currentPage = 1; store.load({start: 0}); me.hasSearch = true; this.getTrigger("clear").show(); }, + createFilter: function (property, term) { + return Ext.create("PartKeepr.util.Filter", { + property: property, + value: "%" + term + "%", + operator: 'like' + }); + }, /** * Sets the store to use * diff --git a/src/PartKeepr/FrontendBundle/Resources/views/index.html.twig b/src/PartKeepr/FrontendBundle/Resources/views/index.html.twig @@ -87,6 +87,7 @@ '@PartKeeprFrontendBundle/Resources/public/js/Components/Auth/WSSEAuthenticationProvider.js' '@PartKeeprFrontendBundle/Resources/public/js/Data/store/TipOfTheDayStore.js' '@PartKeeprFrontendBundle/Resources/public/js/Data/store/TipOfTheDayHistoryStore.js' + '@PartKeeprFrontendBundle/Resources/public/js/Data/store/SystemPreferenceStore.js' '@PartKeeprFrontendBundle/Resources/public/js/Data/store/UserProvidersStore.js' '@PartKeeprFrontendBundle/Resources/public/js/Models/ProjectReport.js' '@PartKeeprFrontendBundle/Resources/public/js/Models/ProjectReportList.js' @@ -234,6 +235,11 @@ '@PartKeeprFrontendBundle/Resources/public/js/Components/CategoryEditor/CategoryEditorForm.js' '@PartKeeprFrontendBundle/Resources/public/js/Components/Picker/CharPicker.js' '@PartKeeprFrontendBundle/Resources/public/js/Components/Widgets/StorageLocationPicker.js' + '@PartKeeprFrontendBundle/Resources/public/js/Components/SystemPreferences/Panel.js' + '@PartKeeprFrontendBundle/Resources/public/js/Components/SystemPreferences/Tree.js' + '@PartKeeprFrontendBundle/Resources/public/js/Components/SystemPreferences/PreferenceEditor.js' + '@PartKeeprFrontendBundle/Resources/public/js/Components/SystemPreferences/Preferences/FulltextSearch.js' + '@PartKeeprFrontendBundle/Resources/public/js/Components/Widgets/FieldSelector.js' '@PartKeeprFrontendBundle/Resources/public/js/Models/Message.js' '@PartKeeprFrontendBundle/Resources/public/js/Ext.ux.Wizard.Card.js' '@PartKeeprFrontendBundle/Resources/public/js/Ext.ux.Wizard.Header.js' diff --git a/src/PartKeepr/SystemPreferenceBundle/Action/DeletePreferenceAction.php b/src/PartKeepr/SystemPreferenceBundle/Action/DeletePreferenceAction.php @@ -0,0 +1,47 @@ +<?php + +namespace PartKeepr\SystemPreferenceBundle\Action; + +use Dunglas\ApiBundle\Action\ActionUtilTrait; +use Dunglas\ApiBundle\Exception\RuntimeException; +use PartKeepr\CategoryBundle\Exception\RootNodeNotFoundException; +use PartKeepr\SystemPreferenceBundle\Service\SystemPreferenceService; +use Symfony\Component\HttpFoundation\Request; + +/** + * Returns the tree root node. + */ +class DeletePreferenceAction +{ + use ActionUtilTrait; + + /** + * @var SystemPreferenceService + */ + private $systemPreferenceService; + + public function __construct( + SystemPreferenceService $systemPreferenceService + ) { + $this->systemPreferenceService = $systemPreferenceService; + } + + /** + * Retrieves a collection of resources. + * + * @param Request $request + * + * @throws \Exception If the format is invalid + * @throws RuntimeException|RootNodeNotFoundException + * + * @return array|\Dunglas\ApiBundle\Model\PaginatorInterface|\Traversable + */ + public function __invoke(Request $request) + { + if ($request->request->has('preferenceKey')) { + $this->systemPreferenceService->deletePreference($request->request->get('preferenceKey')); + } else { + throw new \Exception('Invalid format'); + } + } +} diff --git a/src/PartKeepr/SystemPreferenceBundle/Action/GetPreferencesAction.php b/src/PartKeepr/SystemPreferenceBundle/Action/GetPreferencesAction.php @@ -0,0 +1,68 @@ +<?php + +namespace PartKeepr\SystemPreferenceBundle\Action; + +use Dunglas\ApiBundle\Action\ActionUtilTrait; +use Dunglas\ApiBundle\Api\ResourceInterface; +use Dunglas\ApiBundle\Exception\RuntimeException; +use PartKeepr\CategoryBundle\Exception\RootNodeNotFoundException; +use PartKeepr\SystemPreferenceBundle\Service\SystemPreferenceService; +use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Serializer\Serializer; + +/** + * Returns the tree root node. + */ +class GetPreferencesAction +{ + use ActionUtilTrait; + + /** + * @var SystemPreferenceService + */ + private $systemPreferenceService; + + /** + * @var Serializer + */ + private $serializer; + + public function __construct( + SystemPreferenceService $systemPreferenceService, + Serializer $serializer + ) { + $this->systemPreferenceService = $systemPreferenceService; + $this->serializer = $serializer; + } + + /** + * Retrieves a collection of resources. + * + * @param Request $request + * + * @throws RuntimeException|RootNodeNotFoundException + * + * @return JsonResponse + */ + public function __invoke(Request $request) + { + $preferences = $this->systemPreferenceService->getPreferences(); + + /** + * @var ResourceInterface $resourceType + */ + list($resourceType) = $this->extractAttributes($request); + + /* + * @var ResourceInterface $resourceType + */ + $serializedData = $this->serializer->normalize( + $preferences, + 'json', + $resourceType->getNormalizationContext() + ); + + return new JsonResponse($serializedData); + } +} diff --git a/src/PartKeepr/SystemPreferenceBundle/Action/SetPreferenceAction.php b/src/PartKeepr/SystemPreferenceBundle/Action/SetPreferenceAction.php @@ -0,0 +1,73 @@ +<?php + +namespace PartKeepr\SystemPreferenceBundle\Action; + +use Dunglas\ApiBundle\Action\ActionUtilTrait; +use Dunglas\ApiBundle\Api\ResourceInterface; +use Dunglas\ApiBundle\Exception\RuntimeException; +use PartKeepr\CategoryBundle\Exception\RootNodeNotFoundException; +use PartKeepr\SystemPreferenceBundle\Service\SystemPreferenceService; +use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Serializer\Serializer; + +/** + * Returns the tree root node. + */ +class SetPreferenceAction +{ + use ActionUtilTrait; + + /** + * @var SystemPreferenceService + */ + private $systemPreferenceService; + + /** + * @var Serializer + */ + private $serializer; + + public function __construct( + SystemPreferenceService $systemPreferenceService, + Serializer $serializer + ) { + $this->systemPreferenceService = $systemPreferenceService; + $this->serializer = $serializer; + } + + /** + * Retrieves a collection of resources. + * + * @param Request $request + * + * @throws \Exception If the format is invalid + * @throws RuntimeException|RootNodeNotFoundException + * + * @return JsonResponse + */ + public function __invoke(Request $request) + { + $data = json_decode($request->getContent()); + + if (property_exists($data, 'preferenceKey') && property_exists($data, 'preferenceValue')) { + $preference = $this->systemPreferenceService->setSystemPreference($data->preferenceKey, + $data->preferenceValue); + } else { + throw new \Exception('Invalid format'); + } + + /** + * @var ResourceInterface $resourceType + */ + list($resourceType) = $this->extractAttributes($request); + + $serializedData = $this->serializer->normalize( + $preference, + 'json', + $resourceType->getNormalizationContext() + ); + + return new JsonResponse($serializedData); + } +} diff --git a/src/PartKeepr/SystemPreferenceBundle/DependencyInjection/Configuration.php b/src/PartKeepr/SystemPreferenceBundle/DependencyInjection/Configuration.php @@ -0,0 +1,23 @@ +<?php +namespace PartKeepr\SystemPreferenceBundle\DependencyInjection; + +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; + +class Configuration implements ConfigurationInterface +{ + /** + * {@inheritdoc} + */ + public function getConfigTreeBuilder() + { + $treeBuilder = new TreeBuilder(); + $treeBuilder->root('part_keepr_system_preference'); + + // Here you should define the parameters that are allowed to + // configure your bundle. See the documentation linked above for + // more information on that topic. + + return $treeBuilder; + } +}+ \ No newline at end of file diff --git a/src/PartKeepr/SystemPreferenceBundle/DependencyInjection/PartKeeprSystemPreferenceExtension.php b/src/PartKeepr/SystemPreferenceBundle/DependencyInjection/PartKeeprSystemPreferenceExtension.php @@ -0,0 +1,23 @@ +<?php +namespace PartKeepr\SystemPreferenceBundle\DependencyInjection; + +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader; +use Symfony\Component\HttpKernel\DependencyInjection\Extension; + +class PartKeeprSystemPreferenceExtension extends Extension +{ + /** + * {@inheritdoc} + */ + public function load(array $configs, ContainerBuilder $container) + { + $configuration = new Configuration(); + $this->processConfiguration($configuration, $configs); + + $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('services.xml'); + $loader->load('actions.xml'); + } +}+ \ No newline at end of file diff --git a/src/PartKeepr/SystemPreferenceBundle/Entity/SystemPreference.php b/src/PartKeepr/SystemPreferenceBundle/Entity/SystemPreference.php @@ -0,0 +1,85 @@ +<?php +namespace PartKeepr\SystemPreferenceBundle\Entity; + +use Doctrine\ORM\Mapping as ORM; +use PartKeepr\DoctrineReflectionBundle\Annotation\IgnoreIds; +use PartKeepr\DoctrineReflectionBundle\Annotation\TargetService; +use Symfony\Component\Serializer\Annotation\Groups; + +/** + * Represents a system preference entry. + * + * System preferences are a simple key => value mechanism, where the developer can + * specify the key and value himself. + * + * Note that values are stored internally as serialized PHP values to keep their type. + * + * @ORM\Entity + * @TargetService(uri="/api/system_preferences") + * @IgnoreIds() + **/ +class SystemPreference +{ + /** + * Defines the key of the system preference. + * + * @ORM\Column(type="string",length=255) + * @ORM\Id() + * + * @Groups({"default"}) + * + * @var string + */ + private $preferenceKey; + + /** + * Defines the value. Note that the value is internally stored as a serialized string. + * + * @ORM\Column(type="text") + * + * @Groups({"default"}) + * + * @var mixed + */ + private $preferenceValue; + + /** + * Returns the key of this entry. + * + * @return string + */ + public function getPreferenceKey() + { + return $this->preferenceKey; + } + + /** + * Sets the key for this user preference. + * + * @param string $key The key name + */ + public function setPreferenceKey($key) + { + $this->preferenceKey = $key; + } + + /** + * Returns the value for this entry. + * + * @return mixed The value + */ + public function getPreferenceValue() + { + return unserialize($this->preferenceValue); + } + + /** + * Sets the value for this entry. + * + * @param mixed $value + */ + public function setPreferenceValue($value) + { + $this->preferenceValue = serialize($value); + } +} diff --git a/src/PartKeepr/SystemPreferenceBundle/Exceptions/SystemPreferenceNotFoundException.php b/src/PartKeepr/SystemPreferenceBundle/Exceptions/SystemPreferenceNotFoundException.php @@ -0,0 +1,15 @@ +<?php +namespace PartKeepr\SystemPreferenceBundle\Exceptions; + +use PartKeepr\CoreBundle\Exceptions\TranslatableException; + +/** + * Is thrown when the system preference could not be found. + */ +class SystemPreferenceNotFoundException extends TranslatableException +{ + public function getMessageKey() + { + return 'The requested system preference was not found'; + } +} diff --git a/src/PartKeepr/SystemPreferenceBundle/PartKeeprSystemPreferenceBundle.php b/src/PartKeepr/SystemPreferenceBundle/PartKeeprSystemPreferenceBundle.php @@ -0,0 +1,9 @@ +<?php + +namespace PartKeepr\SystemPreferenceBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class PartKeeprSystemPreferenceBundle extends Bundle +{ +} diff --git a/src/PartKeepr/SystemPreferenceBundle/Resources/config/actions.xml b/src/PartKeepr/SystemPreferenceBundle/Resources/config/actions.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" ?> + +<container xmlns="http://symfony.com/schema/dic/services" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> + + <services> + <service id="partkeepr.system_preference.get_preferences" + class="PartKeepr\SystemPreferenceBundle\Action\GetPreferencesAction"> + <argument type="service" id="partkeepr.system_preference_service"/> + <argument type="service" id="api.serializer"/> + </service> + <service id="partkeepr.system_preference.set_preference" class="PartKeepr\SystemPreferenceBundle\Action\SetPreferenceAction"> + <argument type="service" id="partkeepr.system_preference_service"/> + <argument type="service" id="api.serializer"/> + </service> + <service id="partkeepr.system_preference.delete_preference" + class="PartKeepr\SystemPreferenceBundle\Action\DeletePreferenceAction"> + <argument type="service" id="partkeepr.system_preference_service"/> + </service> + </services> +</container> diff --git a/src/PartKeepr/SystemPreferenceBundle/Resources/config/services.xml b/src/PartKeepr/SystemPreferenceBundle/Resources/config/services.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" ?> + +<container xmlns="http://symfony.com/schema/dic/services" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> + + <services> + <service id="partkeepr.system_preference_service" class="PartKeepr\SystemPreferenceBundle\Service\SystemPreferenceService"> + <argument type="service" id="doctrine.orm.entity_manager"/> + </service> + </services> +</container> diff --git a/src/PartKeepr/SystemPreferenceBundle/Service/SystemPreferenceService.php b/src/PartKeepr/SystemPreferenceBundle/Service/SystemPreferenceService.php @@ -0,0 +1,122 @@ +<?php +namespace PartKeepr\SystemPreferenceBundle\Service; + + +use Doctrine\ORM\EntityManager; +use Doctrine\ORM\NoResultException; +use PartKeepr\SystemPreferenceBundle\Entity\SystemPreference; +use PartKeepr\SystemPreferenceBundle\Exceptions\SystemPreferenceNotFoundException; + +class SystemPreferenceService +{ + /* + * @var EntityManager + */ + private $entityManager; + + public function __construct(EntityManager $entityManager) + { + $this->entityManager = $entityManager; + } + + /** + * Creates or updates a preference for a given user. + * + * @param string $key The key to set + * @param string $value The value to set + * + * @return SystemPreference The user preference + */ + public function setSystemPreference($key, $value) + { + $dql = 'SELECT sp FROM PartKeepr\SystemPreferenceBundle\Entity\SystemPreference sp WHERE sp.preferenceKey = :key'; + + $query = $this->entityManager->createQuery($dql); + $query->setParameter('key', $key); + + try { + $systemPreference = $query->getSingleResult(); + } catch (\Exception $e) { + $systemPreference = new SystemPreference(); + $systemPreference->setPreferenceKey($key); + + $this->entityManager->persist($systemPreference); + } + + $systemPreference->setPreferenceValue($value); + + $this->entityManager->flush(); + + return $systemPreference; + } + + /** + * Returns a specific preference value + * + * @param string $key The preference key to retrieve + * + * @throws \PartKeepr\AuthBundle\Exceptions\UserPreferenceNotFoundException Thrown if the preference key was not found + * + * @return string The preference string + */ + public function getSystemPreferenceValue($key) + { + $systemPreference = $this->getPreference($key); + + return $systemPreference->getPreferenceValue(); + } + + /** + * Returns a specific preference object + * + * @param string $key The preference key to retrieve + * + * @throws SystemPreferenceNotFoundException Thrown if the preference key was not found + * + * @return SystemPreference The preference object + */ + public function getPreference($key) + { + $dql = "SELECT sp FROM PartKeepr\SystemPreferenceBundle\Entity\SystemPreference sp WHERE sp.preferenceKey = :key"; + + $query = $this->entityManager->createQuery($dql); + $query->setParameter('key', $key); + + try { + $sp = $query->getSingleResult(); + + return $sp; + } catch (NoResultException $e) { + throw new SystemPreferenceNotFoundException($key); + } + } + + /** + * Returns all system preferences + * + * @return SystemPreference[] An array of SystemPreference objects + */ + public function getPreferences() + { + $dql = "SELECT sp FROM PartKeepr\SystemPreferenceBundle\Entity\SystemPreference sp"; + + $query = $this->entityManager->createQuery($dql); + return $query->getResult(); + } + + /** + * Removes a specific system preference + * + * @param string $key The key to delete + */ + public function deletePreference($key) + { + $dql = "DELETE FROM PartKeepr\SystemPreferenceBundle\Entity\SystemPreference sp WHERE sp.preferenceKey = :key"; + + $query = $this->entityManager->createQuery($dql); + $query->setParameter('key', $key); + + $query->execute(); + } + +}+ \ No newline at end of file diff --git a/src/PartKeepr/SystemPreferenceBundle/Tests/SystemPreferenceTest.php b/src/PartKeepr/SystemPreferenceBundle/Tests/SystemPreferenceTest.php @@ -0,0 +1,53 @@ +<?php + +namespace PartKeepr\SystemPreferenceBundle\Tests; + +use PartKeepr\CoreBundle\Tests\WebTestCase; +use PartKeepr\SystemPreferenceBundle\Exceptions\SystemPreferenceNotFoundException; + +class SystemPreferenceTest extends WebTestCase +{ + public function setUp() + { + $this->loadFixtures([]); + } + + public function testSystemPreferenceService() { + $this->getContainer()->get("partkeepr.system_preference_service")->setSystemPreference("foo", "bar"); + + $this->assertEquals("bar", $this->getContainer()->get("partkeepr.system_preference_service")->getSystemPreferenceValue("foo")); + + $this->getContainer()->get("partkeepr.system_preference_service")->setSystemPreference("foo", "bar2"); + + $this->assertEquals("bar2", $this->getContainer()->get("partkeepr.system_preference_service")->getSystemPreferenceValue("foo")); + + $preference = $this->getContainer()->get("partkeepr.system_preference_service")->getPreference("foo"); + $this->assertEquals("foo", $preference->getPreferenceKey()); + + $this->expectException(SystemPreferenceNotFoundException::class); + $this->assertEquals("bar2", $this->getContainer()->get("partkeepr.system_preference_service")->getSystemPreferenceValue("foo2")); + } + + public function testSystemPreferenceCreate() + { + $client = static::makeClient(true); + + $parameters = [ + "preferenceKey" => "foobar", + "@type" => "SystemPreference", + "preferenceValue" => "test" + ]; + + // First test: Ensure invalid auth key is returned + $client->request( + 'POST', + '/api/system_preferences', + [], + [], + [], + json_encode($parameters) + ); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + } +}