API-CHANGE: improved DMS tagging functionality

This commit is contained in:
Julian Seidenberg 2012-07-27 11:26:30 +12:00
parent de93686a68
commit 03da4c3ff5
4 changed files with 157 additions and 13 deletions

View File

@ -6,6 +6,7 @@ class DMSDocument extends DataObject implements DMSDocumentInterface {
"Folder" => "Varchar(255)", // eg. 0
"Title" => 'Varchar(1024)', // eg. "Energy Saving Report for Year 2011, New Zealand LandCorp"
"Description" => 'Text',
"LastChanged" => 'DateTime' //when this document was created or last replaced (small changes like updating title don't count)
);
static $many_many = array(
@ -70,28 +71,51 @@ class DMSDocument extends DataObject implements DMSDocumentInterface {
$tag = new DMSTag();
$tag->Category = $category;
$tag->Value = $value;
$tag->MultiValue = true;
$tag->write();
$tag->Documents()->add($this);
} else {
//add the relation between the tag and document
foreach($currentTag as $tagObj) {
$tagObj->Documents()->add($this);
}
}
} else {
//single value tag
$currentTag = $this->Tags()->filter(array('Category' => $category));
if (!$currentTag) {
$tag = null;
if ($currentTag->Count() == 0) {
//create the single-value tag
$tag = new DMSTag();
$tag->Category = $category;
$tag->Value = $value;
$tag->MultiValue = false;
$tag->write();
$tag->Documents()->add($this);
} else {
//update the single value tag
$tag = $currentTag->first();
$tag->Value = $value;
$tag->MultiValue = false;
$tag->write();
}
//regardless of whether we created a new tag or are just updating an existing one, add the relation
$tag->Documents()->add($this);
}
}
protected function getTagsObjects($category, $value = null) {
$valueFilter = array("Category" => $category);
if (!empty($value)) $valueFilter['Value'] = $value;
if ($this->ID == 2) {
Debug::Show($this);
Debug::Show($this->Tags());
}
$tags = $this->Tags()->filter($valueFilter);
return $tags;
}
/**
* Fetches all tags associated with this DMSDocument within a given category. If a value is specified this method
* tries to fetch that specific tag.
@ -101,16 +125,13 @@ class DMSDocument extends DataObject implements DMSDocumentInterface {
* @return array of Strings of all the tags or null if there is no match found
*/
function getTags($category, $value = null) {
$valueFilter = array("Category" => $category);
if (!empty($value)) $valueFilter['Value'] = $value;
$tag = $this->Tags()->filter($valueFilter);
$tags = $this->getTagsObjects($category, $value);
//convert DataList into array of Values
$returnArray = null;
if ($tag->Count() > 0) {
if ($tags->Count() > 0) {
$returnArray = array();
foreach($tag as $t) {
foreach($tags as $t) {
$returnArray[] = $t->Value;
}
}
@ -141,7 +162,27 @@ class DMSDocument extends DataObject implements DMSDocumentInterface {
* @return null
*/
function removeTag($category, $value = null) {
// TODO: Implement removeTag() method.
$tags = $this->getTagsObjects($category, $value);
if ($tags->Count() > 0) {
$tagsToDelete = array();
foreach($tags as $t) {
$documentList = $t->Documents();
//remove the relation between the tag and the document
$documentList->remove($this);
//delete the entire tag if it has no relations left
if ($documentList->Count() == 0) $tagsToDelete[] = $t->ID;
}
//delete after the loop, so it doesn't conflict with the loop of the $tags list
foreach($tagsToDelete as $tID) {
$tag = DataObject::get_by_id("DMSTag",$tID);
$tag->delete();
}
}
}
/**
@ -149,7 +190,10 @@ class DMSDocument extends DataObject implements DMSDocumentInterface {
* @return null
*/
function removeAllTags() {
// TODO: Implement removeAllTags() method.
$allTags = $this->Tags();
foreach($allTags as $tag) {
if ($tag->Documents()->Count() == 0) $tag->delete();
}
}
/**
@ -278,4 +322,14 @@ class DMSDocument extends DataObject implements DMSDocumentInterface {
parent::delete();
}
/**
* Takes a File object or a String (path to a file) and copies it into the DMS, replacing the original document file
* but keeping the rest of the document unchanged.
* @param $file File object, or String that is path to a file to store
* @return DMSDocumentInstance Document object that we replaced the file in
*/
function replaceDocument($file) {
// TODO: Implement replace() method.
}
}

View File

@ -5,8 +5,9 @@
class DMSTag extends DataObject {
static $db = array(
'Category' => 'varchar(1024)',
'Value' => 'varchar(1024)'
'Category' => 'Varchar(1024)',
'Value' => 'Varchar(1024)',
'MultiValue' => 'Boolean(1)'
);
static $belongs_many_many = array(

View File

@ -123,6 +123,14 @@ interface DMSDocumentInterface {
*/
function downloadLink();
/**
* Takes a File object or a String (path to a file) and copies it into the DMS, replacing the original document file
* but keeping the rest of the document unchanged.
* @param $file File object, or String that is path to a file to store
* @return DMSDocumentInstance Document object that we replaced the file in
*/
function replaceDocument($file);
/**
* Hides the DMSDocument, so it does not show up when getByPage($myPage) is called
* (without specifying the $showEmbargoed = true parameter). This is similar to expire, except that this method

View File

@ -4,7 +4,6 @@ class DMSTagTest extends SapphireTest {
//static $fixture_file = "dms/tests/dmstest.yml";
function testAddingTags() {
$doc = new DMSDocument();
$doc->Filename = "test file";
$doc->Folder = "0";
@ -20,5 +19,87 @@ class DMSTagTest extends SapphireTest {
$this->assertNotNull($fruits,"Something returned for fruit tags");
$this->assertEquals(count($fruits),3,"3 fruit tags returned");
$this->assertTrue(in_array("banana",$fruits),"correct fruit tags returned");
//sneakily create another document and link one of the tags to that, too
$doc2 = new DMSDocument();
$doc2->Filename = "sneaky file";
$doc2->Folder = "0";
$doc2->write();
$doc2->addTag("fruit","banana");
$fruits = $doc->getTags("fruit");
$this->assertNotNull($fruits,"Something returned for fruit tags");
$this->assertEquals(count($fruits),1,"Only 1 fruit tags returned");
//tidy up by deleting all tags from doc 1 (But the banana fruit tag should remain)
$doc->removeAllTags();
//banana fruit remains
$doc2->getTags("fruit");
$this->assertNotNull($fruits,"Something returned for fruit tags");
$this->assertEquals(count($fruits),1,"Only 1 fruit tags returned");
$tags = DataObject::get("DMSTag");
$this->assertEquals($tags->Count(),1,"A single DMS tag objects remain after deletion of all tags on doc1");
//delete all tags off doc2 to complete the tidy up
$doc2->removeAllTags();
$tags = DataObject::get("DMSTag");
$this->assertEquals($tags->Count(),0,"No DMS tag objects remain after deletion");
}
function testRemovingTags() {
$doc = new DMSDocument();
$doc->Filename = "test file";
$doc->Folder = "0";
$doc->write();
$doc->addTag("fruit","banana");
$doc->addTag("fruit","orange");
$doc->addTag("fruit","apple");
$doc->addTag("company","apple");
$doc->addTag("company","SilverStripe");
$companies = $doc->getTags("company");
$this->assertNotNull($companies,"Companies returned before deletion");
$this->assertEquals(count($companies),2,"Two companies returned before deletion");
//delete an entire category
$doc->removeTag("company");
$companies = $doc->getTags("company");
$this->assertNull($companies,"All companies deleted");
$fruit = $doc->getTags("fruit");
$this->assertEquals(count($fruit),3,"Three fruits returned before deletion");
//delete a single tag
$doc->removeTag("fruit","apple");
$fruit = $doc->getTags("fruit");
$this->assertEquals(count($fruit),2,"Two fruits returned after deleting one");
//delete a single tag
$doc->removeTag("fruit","orange");
$fruit = $doc->getTags("fruit");
$this->assertEquals(count($fruit),1,"One fruits returned after deleting two");
//nothing happens when deleting tag that doesn't exist
$doc->removeTag("fruit","jellybean");
$fruit = $doc->getTags("fruit");
$this->assertEquals(count($fruit),1,"One fruits returned after attempting to delete non-existent fruit");
//delete the last fruit
$doc->removeTag("fruit","banana");
$fruit = $doc->getTags("fruit");
$this->assertNull($fruit,"All fruits deleted");
$tags = DataObject::get("DMSTag");
$this->assertEquals($tags->Count(),0,"No DMS tag objects remain after deletion");
}
}