VCALENDAR converter: fixes empty CATEGORIES property
[tine20] / tine20 / Tinebase / Model / Tag.php
1 <?php
2 /**
3  * Tine 2.0
4  * 
5  * @package     Tinebase
6  * @subpackage  Tags
7  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
8  * @copyright   Copyright (c) 2008-2012 Metaways Infosystems GmbH (http://www.metaways.de)
9  * @author      Cornelius Weiss <c.weiss@metaways.de>
10  */
11
12 /**
13  * defines the datatype for one tag
14  * 
15  * @package     Tinebase
16  * @subpackage  Tags
17  */
18 class Tinebase_Model_Tag extends Tinebase_Record_Abstract
19 {
20     /**
21      * Type of a shared tag
22      */
23     const TYPE_SHARED = 'shared';
24     /**
25      * Type of a personal tag
26      */
27     const TYPE_PERSONAL = 'personal';
28     
29     /**
30      * key in $_validators/$_properties array for the filed which 
31      * represents the identifier
32      * 
33      * @var string
34      */    
35     protected $_identifier = 'id';
36     
37     /**
38      * application the record belongs to
39      *
40      * @var string
41      */
42     protected $_application = 'Tinebase';
43     
44     /**
45      * list of zend inputfilter
46      * 
47      * this filter get used when validating user generated content with Zend_Input_Filter
48      *
49      * @var array
50      */
51     protected $_filters = array(
52         'name'              => 'StringTrim'
53     );
54     
55     /**
56      * list of zend validator
57      * 
58      * this validators get used when validating user generated content with Zend_Input_Filter
59      *
60      * @var array
61      */
62     protected $_validators = array(
63         'id'                     => array('Alnum', 'allowEmpty' => true),
64         'type'                   => array(array('InArray', array(self::TYPE_PERSONAL, self::TYPE_SHARED))),
65         'owner'                  => array('allowEmpty' => true),
66         'name'                   => array('presence' => 'required'),
67         'description'            => array('allowEmpty' => true),
68         'color'                  => array('allowEmpty' => true, array('regex', '/^#[0-9a-fA-F]{6}$/')),
69         'occurrence'             => array('allowEmpty' => true),
70         'selection_occurrence'   => array('allowEmpty' => true), // not persistent
71         'account_grants'         => array('allowEmpty' => true),
72         'created_by'             => array('allowEmpty' => true),
73         'creation_time'          => array('allowEmpty' => true),
74         'last_modified_by'       => array('allowEmpty' => true),
75         'last_modified_time'     => array('allowEmpty' => true),
76         'is_deleted'             => array('allowEmpty' => true),
77         'deleted_time'           => array('allowEmpty' => true),
78         'deleted_by'             => array('allowEmpty' => true),
79         'seq'                    => array('allowEmpty' => true),
80     );
81     
82     protected $_datetimeFields = array(
83         'creation_time',
84         'last_modified_time',
85         'deleted_time',
86     );
87     
88     /**
89      * returns containername
90      *
91      * @return string
92      */
93     public function __toString()
94     {
95         return $this->name;
96     }
97     
98     /**
99      * converts an array of tags names to a recordSet of Tinebase_Model_Tag
100      * 
101      * @param  iteratable           $tagNames
102      * @param  bool                 $implicitAddMissingTags
103      * @return Tinebase_Record_RecordSet
104      */
105     public static function resolveTagNameToTag($tagNames, $applicationName, $implicitAddMissingTags = true)
106     {
107         if (empty($tagNames)) {
108             return new Tinebase_Record_RecordSet('Tinebase_Model_Tag');
109         }
110         
111         $resolvedTags = array();
112         
113         foreach ((array)$tagNames as $tagName) {
114             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) 
115                 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Trying to allocate tag ' . $tagName);
116             
117             $tagName = trim($tagName);
118             if (empty($tagName)) {
119                 continue;
120             }
121             
122             $existingTags = Tinebase_Tags::getInstance()->searchTags(
123                 new Tinebase_Model_TagFilter(array(
124                     'name'        => $tagName,
125                     'application' => $applicationName
126                 )), 
127                 new Tinebase_Model_Pagination(array(
128                     'sort'    => 'type', // prefer shared over personal
129                     'dir'     => 'DESC',
130                     'limit'   => 1
131                 ))
132             );
133             
134             if (count($existingTags) === 1) {
135                 //var_dump($existingTags->toArray());
136                 $resolvedTags[] = $existingTags->getFirstRecord();
137         
138             } elseif ($implicitAddMissingTags === true) {
139                 // No tag found, lets create a personal tag
140                 $resolvedTag = Tinebase_Tags::GetInstance()->createTag(new Tinebase_Model_Tag(array(
141                     'type'        => Tinebase_Model_Tag::TYPE_PERSONAL,
142                     'name'        => $tagName
143                 )));
144                 
145                 $resolvedTags[] = $resolvedTag;
146             }
147         }
148         
149         return new Tinebase_Record_RecordSet('Tinebase_Model_Tag', $resolvedTags);
150     }
151 }