partkeepr

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

commit 2bb4f235cda72824aa2711719ead1fb710548db8
parent 6692fd0e2d7fb470cfc8d57144c2754206be1d01
Author: Felicitus <felicitus@felicitus.org>
Date:   Mon, 20 Jun 2011 16:51:50 +0200

Merge branch 'TIMO'

Diffstat:
Afrontend/js/Components/Footprint/FootprintTree.js | 163+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Afrontend/js/Components/Part/PartCategoryTree.js | 39+++++++++++++++++++++++++++++++++++++++
Afrontend/js/Models/AbstractCategory.js | 5+++++
Afrontend/js/Models/FootprintCategory.js | 14++++++++++++++
Afrontend/js/Models/PartCategory.js | 14++++++++++++++
Asetup/data/footprints/BGA/SBGA-256.png | 0
Asetup/data/footprints/BGA/SBGA-304.png | 0
Asetup/data/footprints/BGA/SBGA-432.png | 0
Asetup/data/footprints/DIP/CERDIP-14.png | 0
Asetup/data/footprints/DIP/CERDIP-16.png | 0
Asetup/data/footprints/DIP/CERDIP-18.png | 0
Asetup/data/footprints/DIP/CERDIP-20.png | 0
Asetup/data/footprints/DIP/CERDIP-24-N.png | 0
Asetup/data/footprints/DIP/CERDIP-24-W.png | 0
Asetup/data/footprints/DIP/CERDIP-28.png | 0
Asetup/data/footprints/DIP/CERDIP-40.png | 0
Asetup/data/footprints/DIP/CERDIP-8.png | 0
Asetup/data/footprints/DIP/PDIP-14.png | 0
Asetup/data/footprints/DIP/PDIP-16.png | 0
Asetup/data/footprints/DIP/PDIP-8.png | 0
Asrc/de/RaumZeitLabor/PartKeepr/Category/AbstractCategory.php | 153+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/de/RaumZeitLabor/PartKeepr/Category/AbstractCategoryManager.php | 151++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/de/RaumZeitLabor/PartKeepr/Category/AbstractCategoryService.php | 140+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/de/RaumZeitLabor/PartKeepr/Footprint/Footprint.php | 2+-
Msrc/de/RaumZeitLabor/PartKeepr/Footprint/FootprintService.php | 2+-
Asrc/de/RaumZeitLabor/PartKeepr/FootprintCategory/FootprintCategory.php | 17+++++++++++++++++
Asrc/de/RaumZeitLabor/PartKeepr/FootprintCategory/FootprintCategoryManager.php | 43+++++++++++++++++++++++++++++++++++++++++++
Asrc/de/RaumZeitLabor/PartKeepr/FootprintCategory/FootprintCategoryService.php | 10++++++++++
Asrc/de/RaumZeitLabor/PartKeepr/PartCategory/PartCategory.php | 17+++++++++++++++++
Asrc/de/RaumZeitLabor/PartKeepr/PartCategory/PartCategoryManager.php | 43+++++++++++++++++++++++++++++++++++++++++++
Asrc/de/RaumZeitLabor/PartKeepr/PartCategory/PartCategoryService.php | 10++++++++++
31 files changed, 821 insertions(+), 2 deletions(-)

diff --git a/frontend/js/Components/Footprint/FootprintTree.js b/frontend/js/Components/Footprint/FootprintTree.js @@ -0,0 +1,162 @@ +Ext.define("PartKeepr.FootprintTree", { + extend: 'PartKeepr.CategoryEditorTree', + alias: 'widget.FootprintTree', + + ddGroup: 'FootprintTree', + categoryModel: 'PartKeepr.FootprintCategory', + categoryService: 'FootprintCategory', + folderSort: true, + initComponent: function () { + this.callParent(); + + this.addEvents("itemEdit"); + + this.on("itemclick", Ext.bind(function (t,record) { + if (record.get("footprintId")) { + this.fireEvent("itemEdit", record.get("footprintId")); + } + }, this)); + + this.addButton = Ext.create("Ext.button.Button", + { + tooltip: i18n("Add Footprint"), + icon: 'resources/silkicons/add.png', + handler: Ext.bind(function () { + var r = this.getSelectionModel().getLastSelected(); + + if (r && !r.get("footprintId")) { + this.fireEvent("itemAdd", { category: r.get("id") }); + } else { + /* Try to find the category's parent id */ + if (r.parentNode && !r.parentNode.get("footprintId")) { + this.fireEvent("itemAdd", { category: r.parentNode.get("id") }); + } else { + this.fireEvent("itemAdd"); + } + } + + }, this) + }); + + this.deleteButton = Ext.create("Ext.button.Button", { + tooltip: i18n("Delete Footprint"), + icon: 'resources/silkicons/delete.png', + handler: Ext.bind(function () { + this.fireEvent("itemDelete"); + }, this), + disabled: true + }); + + this.toolbar.add([this.addButton, this.deleteButton]); + + this.getSelectionModel().on("select", this._onItemSelect, this); + this.getSelectionModel().on("deselect", this._onItemDeselect, this); + }, + /** + * Called when an item was selected + */ + _onItemSelect: function (selectionModel, record) { + this._updateDeleteButton(selectionModel, record); + this.fireEvent("itemSelect", record); + }, + /** + * Called when an item was deselected + */ + _onItemDeselect: function (selectionModel, record) { + this._updateDeleteButton(selectionModel, record); + this.fireEvent("itemDeselect", record); + }, + /** + * Called when an item was selected. Enables/disables the delete button. + */ + _updateDeleteButton: function (selectionModel, record) { + /* Right now, we support delete on a single record only */ + if (this.getSelectionModel().getCount() == 1 && record.get("footprintId")) { + this.deleteButton.enable(); + } else { + this.deleteButton.disable(); + } + }, + syncChanges: function (record) { + var oldRecordIndex = PartKeepr.getApplication().getFootprintStore().find("id", record.get("id")); + + if (oldRecordIndex === -1) { + /* Record doesn't exist yet; add it */ + PartKeepr.getApplication().getFootprintStore().add(record); + } else { + var oldRecord = PartKeepr.getApplication().getFootprintStore().getAt(oldRecordIndex); + oldRecord.set("name", record.get("name")); + } + + this.loadCategories(); + }, + _onCategoriesLoaded: function () { + this.callParent(arguments); + var store = PartKeepr.getApplication().getFootprintStore(); + var category_id; + var nodeData, record; + + for (var i=0;i<store.getCount();i++) { + record = store.getAt(i); + + nodeData = { + name: record.getRecordName(), + footprintId: record.get("id"), + leaf: true + }; + + + if (record.get("category") === 0) { + this.getRootNode().firstChild.appendChild(nodeData); + } else { + var node = this.getRootNode().findChild("id", record.get("category"), true); + + if (node) { + node.appendChild(nodeData); + } else { + this.getRootNode().firstChild.appendChild(nodeData); + } + } + + } + + }, + onBeforeDrop: function (node, data, overModel, dropPosition, dropFunction, options) { + var draggedRecord = data.records[0]; + var droppedOn = this.getView().getRecord(node); + + if (droppedOn.get("footprintId")) { + // Target record is a footprint, we don't allow moving categories onto footprints + return false; + } + + if (draggedRecord.get("footprintId")) { + /* Move Footprint */ + var call = new PartKeepr.ServiceCall("Footprint", "moveFootprint"); + + call.setParameter("id", draggedRecord.get("footprintId")); + call.setParameter("targetCategory", droppedOn.get("id")); + call.setHandler(Ext.bind(function () { + var node = this.getRootNode().findChild("footprintId", draggedRecord.get("footprintId"), true); + + var targetNode = this.getRootNode().findChild("id", droppedOn.get("id"), true); + targetNode.expand(); + + node.remove(); + + targetNode.appendChild(node); + + var oldRecordIndex = PartKeepr.getApplication().getFootprintStore().find("id", draggedRecord.get("footprintId")); + var oldRecord = PartKeepr.getApplication().getFootprintStore().getAt(oldRecordIndex); + + oldRecord.set("category", droppedOn.get("id")); + + }, this)); + call.doCall(); + + return false; + } + + } + +});+ \ No newline at end of file diff --git a/frontend/js/Components/Part/PartCategoryTree.js b/frontend/js/Components/Part/PartCategoryTree.js @@ -0,0 +1,38 @@ +Ext.define("PartKeepr.PartCategoryTree", { + extend: 'PartKeepr.CategoryEditorTree', + alias: 'widget.PartCategoryTree', + + ddGroup: 'PartTree', + categoryModel: 'PartKeepr.PartCategory', + categoryService: 'PartCategory', + onBeforeDrop: function (node, data, overModel, dropPosition, dropFunction, options) { + var draggedRecord = data.records[0]; + var droppedOn = this.getView().getRecord(node); + + if (draggedRecord.modelName == "PartKeepr.Part") { + /* Move Part */ + var call = new PartKeepr.ServiceCall("Part", "movePart"); + + if (data.records.length > 1) { + var sources = []; + + for (var i=0;i<data.records.length;i++) { + sources.push(data.records[i].get("id")); + } + + call.setParameter("parts", sources); + } else { + call.setParameter("part", draggedRecord.get("id")); + } + + call.setParameter("targetCategory", droppedOn.get("id")); + call.setHandler(function () { + data.view.store.load(); + }); + call.doCall(); + + return false; + } + + } +});+ \ No newline at end of file diff --git a/frontend/js/Models/AbstractCategory.js b/frontend/js/Models/AbstractCategory.js @@ -0,0 +1,5 @@ +Ext.define("PartKeepr.AbstractCategory", { + extend: "Ext.data.Model", + isCategory: true +}); + diff --git a/frontend/js/Models/FootprintCategory.js b/frontend/js/Models/FootprintCategory.js @@ -0,0 +1,14 @@ +Ext.define("PartKeepr.FootprintCategory", { + extend: "PartKeepr.AbstractCategory", + fields: [ + { name: 'id', type: 'int' }, + { name: 'name', type: 'string' }, + { name: 'description', type: 'string' }, + { name: 'parent', type: 'int' } + ], + proxy: PartKeepr.getRESTProxy("FootprintCategory"), + getRecordName: function () { + return this.get("name"); + } +}); + diff --git a/frontend/js/Models/PartCategory.js b/frontend/js/Models/PartCategory.js @@ -0,0 +1,14 @@ +Ext.define("PartKeepr.PartCategory", { + extend: "PartKeepr.AbstractCategory", + fields: [ + { name: 'id', type: 'int' }, + { name: 'name', type: 'string' }, + { name: 'description', type: 'string' }, + { name: 'parent', type: 'int' } + ], + proxy: PartKeepr.getRESTProxy("PartCategory"), + getRecordName: function () { + return this.get("name"); + } +}); + diff --git a/setup/data/footprints/BGA/SBGA-256.png b/setup/data/footprints/BGA/SBGA-256.png Binary files differ. diff --git a/setup/data/footprints/BGA/SBGA-304.png b/setup/data/footprints/BGA/SBGA-304.png Binary files differ. diff --git a/setup/data/footprints/BGA/SBGA-432.png b/setup/data/footprints/BGA/SBGA-432.png Binary files differ. diff --git a/setup/data/footprints/DIP/CERDIP-14.png b/setup/data/footprints/DIP/CERDIP-14.png Binary files differ. diff --git a/setup/data/footprints/DIP/CERDIP-16.png b/setup/data/footprints/DIP/CERDIP-16.png Binary files differ. diff --git a/setup/data/footprints/DIP/CERDIP-18.png b/setup/data/footprints/DIP/CERDIP-18.png Binary files differ. diff --git a/setup/data/footprints/DIP/CERDIP-20.png b/setup/data/footprints/DIP/CERDIP-20.png Binary files differ. diff --git a/setup/data/footprints/DIP/CERDIP-24-N.png b/setup/data/footprints/DIP/CERDIP-24-N.png Binary files differ. diff --git a/setup/data/footprints/DIP/CERDIP-24-W.png b/setup/data/footprints/DIP/CERDIP-24-W.png Binary files differ. diff --git a/setup/data/footprints/DIP/CERDIP-28.png b/setup/data/footprints/DIP/CERDIP-28.png Binary files differ. diff --git a/setup/data/footprints/DIP/CERDIP-40.png b/setup/data/footprints/DIP/CERDIP-40.png Binary files differ. diff --git a/setup/data/footprints/DIP/CERDIP-8.png b/setup/data/footprints/DIP/CERDIP-8.png Binary files differ. diff --git a/setup/data/footprints/DIP/PDIP-14.png b/setup/data/footprints/DIP/PDIP-14.png Binary files differ. diff --git a/setup/data/footprints/DIP/PDIP-16.png b/setup/data/footprints/DIP/PDIP-16.png Binary files differ. diff --git a/setup/data/footprints/DIP/PDIP-8.png b/setup/data/footprints/DIP/PDIP-8.png Binary files differ. diff --git a/src/de/RaumZeitLabor/PartKeepr/Category/AbstractCategory.php b/src/de/RaumZeitLabor/PartKeepr/Category/AbstractCategory.php @@ -0,0 +1,153 @@ +<?php +namespace de\RaumZeitLabor\PartKeepr\Category; + +use de\RaumZeitLabor\PartKeepr\Util\BaseEntity; +use de\RaumZeitLabor\PartKeepr\Util\Serializable; +use DoctrineExtensions\NestedSet\Node; + +declare(encoding = 'UTF-8'); + +/** + * @MappedSuperclass + * @Table(indexes={@index(name="lft", columns={"lft"}),@index(name="rgt", columns={"rgt"})}) + * + * Represents an abstract category + */ +class AbstractCategory extends BaseEntity implements Node, Serializable { + /** + * The "left" property of the nested set + * @Column(type="integer") + * @var integer + */ + private $lft; + + /** + * The "right" property of the nested set + * @Column(type="integer") + * @var integer + */ + private $rgt; + + /** + * The name of the category + * @Column(length=128) + * @var string + */ + private $name; + + /** + * The description of the category + * @Column(type="text",nullable=true) + * @var string + */ + private $description; + + /** + * Holds the parent node ID. Note that this + * is not a persistant value, but rather calculated + * or set on the fly. + * @var int + */ + private $parent; + + /** + * Sets the name of this category + * @param string $name The name to set + */ + public function setName ($name) { + $this->name = $name; + } + + /** + * Returns the name of this category + * @return string The category name + */ + public function getName () { + return $this->name; + } + + /** + * Sets the parent for this category. + * + * @param int $id The parent node + */ + public function setParent ($id) { + $this->parent = $id; + } + + /** + * Returns the parent node for this node. + * @return int The parent node + */ + public function getParent () { + return $this->parent; + } + + /** + * Sets the description for this category + * @param string $description The description of this category + */ + public function setDescription ($description) { + $this->description = $description; + } + + /** + * Returns the description of this category + * @return string The description + */ + public function getDescription () { + return $this->description; + } + + /** + * (non-PHPdoc) + * @see DoctrineExtensions\NestedSet.Node::getLeftValue() + */ + public function getLeftValue() { + return $this->lft; + } + + /** + * (non-PHPdoc) + * @see DoctrineExtensions\NestedSet.Node::setLeftValue() + */ + public function setLeftValue($lft) { + $this->lft = $lft; + } + + /** + * (non-PHPdoc) + * @see DoctrineExtensions\NestedSet.Node::getRightValue() + */ + public function getRightValue() { + return $this->rgt; + } + + /** + * (non-PHPdoc) + * @see DoctrineExtensions\NestedSet.Node::setRightValue() + */ + public function setRightValue($rgt) { + $this->rgt = $rgt; + } + + /** + * Serializes the entity. + */ + public function serialize () { + return array( + "id" => $this->getId(), + "name" => $this->getName(), + "description" => $this->getDescription() + ); + } + + /** + * (non-PHPdoc) + * @see DoctrineExtensions\NestedSet.Node::__toString() + */ + public function __toString () { + return $this->getName(); + } + +} diff --git a/src/de/RaumZeitLabor/PartKeepr/Category/AbstractCategoryManager.php b/src/de/RaumZeitLabor/PartKeepr/Category/AbstractCategoryManager.php @@ -0,0 +1,150 @@ +<?php +namespace de\raumzeitlabor\PartKeepr\Category; +declare(encoding = 'UTF-8'); + +use de\RaumZeitLabor\PartKeepr\Util\Singleton, + de\RaumZeitLabor\PartKeepr\Category\Category, + de\RaumZeitLabor\PartKeepr\Util\SerializableException, + de\RaumZeitLabor\PartKeepr\Category\Exceptions\CategoryNotFoundException, + de\RaumZeitLabor\PartKeepr\PartKeepr; +use DoctrineExtensions\NestedSet\Manager; +use DoctrineExtensions\NestedSet\Config; +use DoctrineExtensions\NestedSet\NodeWrapper; + +abstract class AbstractCategoryManager extends Singleton { + /** + * Holds the node manager + * @var object The node manager + */ + private $nodeManager; + + protected $categoryClass = "de\RaumZeitLabor\PartKeepr\Category\AbstractCategory"; + + /** + * Returns the node manager. Creates it if it doesn't exist. + * @todo Can this method be made private? + * @return Manager The node manager + */ + public function getNodeManager () { + if (!$this->nodeManager) { + $config = new Config(PartKeepr::getEM(), $this->categoryClass); + + $this->nodeManager = new Manager($config); + } + + return $this->nodeManager; + } + + /** + * Returns the child node id's for a given node id. + * @param integer $id The ID for which to retrieve the child nodes + * @return array An array of the children id's + * @todo Refactor this method name to indicate that it operates on IDs only. + */ + public function getChildNodes ($id) { + $category = $this->getCategory($id); + + $aData = array(); + + foreach ($category->getDescendants() as $cat) { + $aData[] = $cat->getNode()->getId(); + } + return $aData; + } + + /** + * Returns all categories. + * @return The category tree + */ + public function getAllCategories () { + return $this->getNodeManager()->fetchTree(1); + } + + /** + * Ensures that the root node exists. If not, this method creates it. + */ + public function ensureRootExists () { + /* Check if the root node exists */ + $rootNode = $this->getNodeManager()->fetchTree(1); + + if ($rootNode === null) { + $this->createRootNode(); + } + } + + /** + * Returns the root node for the category tree. + * @return The category root node + */ + public function getRootNode () { + return $this->getNodeManager()->fetchTree(1); + } + + /** + * Create the root node for the category tree. + */ + public function createRootNode () { + $rootNode = new $this->categoryClass(); + $rootNode->setName("Root Category"); + $rootNode->setDescription(""); + + $this->getNodeManager()->createRoot($rootNode); + } + + /** + * Adds a given category. + * @param Category $category The category to add to the tree + * @return Category the added category + */ + public function addCategory (AbstractCategory $category) { + $parent = $category->getParent(); + + if ($parent == 0) { + $parent = $this->getRootNode(); + + } else { + + $parent = PartKeepr::getEM()->find($this->categoryClass, $parent); + + $parent = new NodeWrapper($parent, $this->getNodeManager()); + } + + return $parent->addChild($category); + } + + /** + * Deletes the given category ID. + * @param $id int The category id to delete + * @throws CategoryNotFoundException If the category wasn't found + */ + public function deleteCategory ($id) { + $this->getCategory($id)->delete(); + } + + /** + * Returns the category with the given ID. + * @param int $id The category id + * @throws CategoryNotFoundException If the category wasn't found + */ + public function getCategory ($id) { + $category = $this->loadCategoryById($id); + + return new NodeWrapper($category, $this->getNodeManager()); + } + + /** + * Returns the overall category count currently existing. + * @return int The amount of categories in the database + */ + public function getCategoryCount () { + $dql = "SELECT COUNT(c.id) FROM ".$this->categoryClass." c"; + + return PartKeepr::getEM()->createQuery($dql)->getSingleScalarResult(); + } + + protected function loadCategoryById($id) { + $class = $this->categoryClass; + + return $class::loadById($id); + } +}+ \ No newline at end of file diff --git a/src/de/RaumZeitLabor/PartKeepr/Category/AbstractCategoryService.php b/src/de/RaumZeitLabor/PartKeepr/Category/AbstractCategoryService.php @@ -0,0 +1,139 @@ +<?php +namespace de\RaumZeitLabor\PartKeepr\Category; +use de\RaumZeitLabor\PartKeepr\PartKeepr; + +declare(encoding = 'UTF-8'); + +use de\RaumZeitLabor\PartKeepr\Service\Service; +use de\RaumZeitLabor\PartKeepr\Category\CategoryManager; +use DoctrineExtensions\NestedSet\NodeWrapper; + + +abstract class AbstractCategoryService extends Service { + protected $categoryManagerClass = "de\RaumZeitLabor\PartKeepr\Category\AbstractCategoryManager"; + protected $categoryClass = "de\RaumZeitLabor\PartKeepr\Category\AbstractCategory"; + + /** + * Returns all categories found in the system. + * @return array A serialized tree + */ + public function getCategories () { + $categories = $this->getCategoryManager()->getAllCategories( + $this->getParameter("parent", 0)); + + return $this->serializeTree($categories); + } + + /** + * Moves the given category from one to another category. + */ + public function moveCategory () { + $this->requireParameter("category"); + $this->requireParameter("target"); + + $category = $this->getCategoryManager()->getCategory($this->getParameter("category")); + + if (intval($this->getParameter("target", 0)) !== 0) { + + $parent = $this->getCategoryManager()->getCategory($this->getParameter("target")); + + $category->moveAsLastChildOf($parent); + + } + } + + /** + * Deletes the given category. + */ + public function deleteCategory () { + $this->requireParameter("id"); + + $this->getCategoryManager()->deleteCategory($this->getParameter("id")); + + return array("id" => $this->getParameter("id")); + } + + /** + * Updates the given category. + */ + public function update () { + $this->requireParameter("id"); + $this->requireParameter("name"); + + $category = $this->getCategoryManager()->getCategory($this->getParameter("id")); + + $category->getNode()->setName($this->getParameter("name")); + $category->getNode()->setDescription($this->getParameter("description", "")); + + PartKeepr::getEM()->persist($category->getNode()); + + return array("data" => $this->serializeCategory($category)); + } + + public function create () { + $this->requireParameter("name"); + $this->requireParameter("parent"); + + $category = new $this->categoryClass; + $category->setName($this->getParameter("name")); + $category->setDescription($this->getParameter("description", "")); + $category->setParent($this->getParameter("parent")); + + $category = $this->getCategoryManager()->addCategory($category); + + return array("data" => $this->serializeCategory($category)); + } + + private function serializeCategory ($category) { + $data = $category->getNode()->serialize(); + + if ($category->getParent() !== null) { + $data["parent"] = $category->getParent()->getNode()->getId(); + $data["parentName"] = $category->getParent()->getNode()->getName(); + } + + return $data; + } + + /** + * Returns all categories + */ + public function getAllCategories () { + return $this->serializeTree($this->getCategoryManager()->getAllCategories()); + } + + /** + * Serializes the given NodeWrapper as array including all children. + * @param NodeWrapper $node The category nodewrapper to serialize + * @throws \Exception + */ + public function serializeTree (NodeWrapper $node = null) { + if ($node == null) { + throw new \Exception("Node must not be null!"); + } + + $aData = $node->getNode()->serialize(); + + $aData["children"] = array(); + + if (count($node->getChildren()) == 0) { + $aData["leaf"] = true; + } else { + $aData["expanded"] = true; + } + + foreach ($node->getChildren() as $child) { + $aData["children"][] = $this->serializeTree($child); + + } + + return $aData; + } + + public function getCategoryManager () { + $categoryManager = $this->categoryManagerClass; + + return $categoryManager::getInstance(); + } +} +?>+ \ No newline at end of file diff --git a/src/de/RaumZeitLabor/PartKeepr/Footprint/Footprint.php b/src/de/RaumZeitLabor/PartKeepr/Footprint/Footprint.php @@ -133,7 +133,7 @@ class Footprint extends BaseEntity implements Serializable { "id" => $this->getId(), "name" => $this->getName(), "description" => $this->getDescription(), - "image" => is_object($this->getImage()) ? $this->getImage()->serialize() : null, + "image_id" => is_object($this->getImage()) ? $this->getImage()->getId() : null, "category" => is_object($this->getCategory()) ? $this->getCategory()->getId() : null, "attachments" => $this->serializeChildren($this->getAttachments()) ); diff --git a/src/de/RaumZeitLabor/PartKeepr/Footprint/FootprintService.php b/src/de/RaumZeitLabor/PartKeepr/Footprint/FootprintService.php @@ -99,7 +99,7 @@ class FootprintService extends Service implements RestfulService { try { $footprintCategory = FootprintCategory::loadById($this->getParameter("category")); - $fp->setCategory($footprintCategory); + $footprint->setCategory($footprintCategory); } catch (\Exception $e) {} PartKeepr::getEM()->flush(); diff --git a/src/de/RaumZeitLabor/PartKeepr/FootprintCategory/FootprintCategory.php b/src/de/RaumZeitLabor/PartKeepr/FootprintCategory/FootprintCategory.php @@ -0,0 +1,16 @@ +<?php +namespace de\RaumZeitLabor\PartKeepr\FootprintCategory; + +use de\RaumZeitLabor\PartKeepr\Category\AbstractCategory; + +declare(encoding = 'UTF-8'); + +/** + * @Entity + * + * The entity for our footprint categories + * + */ +class FootprintCategory extends AbstractCategory { + +}+ \ No newline at end of file diff --git a/src/de/RaumZeitLabor/PartKeepr/FootprintCategory/FootprintCategoryManager.php b/src/de/RaumZeitLabor/PartKeepr/FootprintCategory/FootprintCategoryManager.php @@ -0,0 +1,42 @@ +<?php +namespace de\RaumZeitLabor\PartKeepr\FootprintCategory; + +use de\RaumZeitLabor\PartKeepr\Category\AbstractCategoryManager; +use DoctrineExtensions\NestedSet\NodeWrapper; +use de\RaumZeitLabor\PartKeepr\Util\SerializableException; +use de\RaumZeitLabor\PartKeepr\PartKeepr; + +class FootprintCategoryManager extends AbstractCategoryManager { + protected $categoryClass = "de\RaumZeitLabor\PartKeepr\FootprintCategory\FootprintCategory"; + + /** + * Deletes the given category ID. + * @param $id int The category id to delete + * @throws CategoryNotFoundException If the category wasn't found + */ + public function deleteCategory ($id) { + $category = $this->getCategory($id); + + try { + + if ($category->hasChildren()) { + $exception = new SerializableException(sprintf(PartKeepr::i18n("Category '%s' contains other categories."), $category->getNode()->getName())); + $exception->setDetail(sprintf(PartKeepr::i18n("You tried to delete the category '%s', but it still contains other categories. Please move the categories or delete them first."), $category->getNode()->getName())); + + throw $exception; + } + + parent::deleteCategory($id); + } catch (\PDOException $e) { + if ($e->getCode() == "23000") { + $exception = new SerializableException(sprintf(PartKeepr::i18n("Category '%s' contains footprints."), $category->getNode()->getName())); + $exception->setDetail(sprintf(PartKeepr::i18n("You tried to delete the category '%s', but it still contains footprints. Please move the footprints to another category."), $category->getNode()->getName())); + + throw $exception; + } else { + throw $e; + } + } + } + +}+ \ No newline at end of file diff --git a/src/de/RaumZeitLabor/PartKeepr/FootprintCategory/FootprintCategoryService.php b/src/de/RaumZeitLabor/PartKeepr/FootprintCategory/FootprintCategoryService.php @@ -0,0 +1,9 @@ +<?php +namespace de\RaumZeitLabor\PartKeepr\FootprintCategory; + +use de\RaumZeitLabor\PartKeepr\Category\AbstractCategoryService; + +class FootprintCategoryService extends AbstractCategoryService { + protected $categoryManagerClass = "de\RaumZeitLabor\PartKeepr\FootprintCategory\FootprintCategoryManager"; + protected $categoryClass = "de\RaumZeitLabor\PartKeepr\FootprintCategory\FootprintCategory"; +}+ \ No newline at end of file diff --git a/src/de/RaumZeitLabor/PartKeepr/PartCategory/PartCategory.php b/src/de/RaumZeitLabor/PartKeepr/PartCategory/PartCategory.php @@ -0,0 +1,16 @@ +<?php +namespace de\RaumZeitLabor\PartKeepr\PartCategory; + +use de\RaumZeitLabor\PartKeepr\Category\AbstractCategory; + +declare(encoding = 'UTF-8'); + +/** + * @Entity + * + * The entity for our part categories + * + */ +class PartCategory extends AbstractCategory { + +}+ \ No newline at end of file diff --git a/src/de/RaumZeitLabor/PartKeepr/PartCategory/PartCategoryManager.php b/src/de/RaumZeitLabor/PartKeepr/PartCategory/PartCategoryManager.php @@ -0,0 +1,42 @@ +<?php +namespace de\RaumZeitLabor\PartKeepr\PartCategory; + +use de\RaumZeitLabor\PartKeepr\Category\AbstractCategoryManager; +use DoctrineExtensions\NestedSet\NodeWrapper; +use de\RaumZeitLabor\PartKeepr\Util\SerializableException; +use de\RaumZeitLabor\PartKeepr\PartKeepr; + +class PartCategoryManager extends AbstractCategoryManager { + protected $categoryClass = "de\RaumZeitLabor\PartKeepr\PartCategory\PartCategory"; + + /** + * Deletes the given category ID. + * @param $id int The category id to delete + * @throws CategoryNotFoundException If the category wasn't found + */ + public function deleteCategory ($id) { + $category = $this->getCategory($id); + + try { + + if ($category->hasChildren()) { + $exception = new SerializableException(sprintf(PartKeepr::i18n("Category '%s' contains other categories."), $category->getNode()->getName())); + $exception->setDetail(sprintf(PartKeepr::i18n("You tried to delete the category '%s', but it still contains other categories. Please move the categories or delete them first."), $category->getNode()->getName())); + + throw $exception; + } + + parent::deleteCategory($id); + } catch (\PDOException $e) { + if ($e->getCode() == "23000") { + $exception = new SerializableException(sprintf(PartKeepr::i18n("Category '%s' contains parts."), $category->getNode()->getName())); + $exception->setDetail(sprintf(PartKeepr::i18n("You tried to delete the category '%s', but it still contains parts. Please move the parts to another category."), $category->getNode()->getName())); + + throw $exception; + } else { + throw $e; + } + } + } + +}+ \ No newline at end of file diff --git a/src/de/RaumZeitLabor/PartKeepr/PartCategory/PartCategoryService.php b/src/de/RaumZeitLabor/PartKeepr/PartCategory/PartCategoryService.php @@ -0,0 +1,9 @@ +<?php +namespace de\RaumZeitLabor\PartKeepr\PartCategory; + +use de\RaumZeitLabor\PartKeepr\Category\AbstractCategoryService; + +class PartCategoryService extends AbstractCategoryService { + protected $categoryManagerClass = "de\RaumZeitLabor\PartKeepr\PartCategory\PartCategoryManager"; + protected $categoryClass = "de\RaumZeitLabor\PartKeepr\PartCategory\PartCategory"; +}+ \ No newline at end of file