root/trunk/midcom/midcom.helper.datamanager2/storage.php

Revision 17556, 9.2 kB (checked in by flack, 4 weeks ago)

yet more PHP5-style constructors

  • Property svn:keywords set to Author Date Id Revision
Line 
1 <?php
2 /**
3  * @package midcom.helper.datamanager2
4  * @author The Midgard Project, http://www.midgard-project.org
5  * @version $Id$
6  * @copyright The Midgard Project, http://www.midgard-project.org
7  * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
8  */
9
10 /**
11  * Datamanager 2 Data storage base class.
12  *
13  * It implements the basic interface required for data storage operations. Naturally,
14  * only the construction of storage backends is suspect to class specific code, the actual
15  * operation should be completely transparent across all storage implementations.
16  *
17  * See the individual subclasses for details about their operation.
18  *
19  * @package midcom.helper.datamanager2
20  */
21 class midcom_helper_datamanager2_storage extends midcom_baseclasses_components_purecode
22 {
23     /**
24      * A reference to the data schema used for processing.
25      *
26      * @var midcom_helper_datamanager2_schema
27      * @access protected
28      */
29     var $_schema = null;
30
31     /**
32      * This is a reference the storage object used by the subclass implementation.
33      * Types <i>may use this reference only for attachment operations and parameter
34      * operations related to attachment operations.</i>
35      *
36      * It can be safely considered that a MidCOM DBA object is available here if the
37      * reference is non-null.
38      *
39      * Since this member is not necessarily populated in all cases, the base API
40      * provides callers with a create_temporary_object helper function: It will put
41      * a temporary object into $object, so that attachment operations can still
42      * be done. The storage object user must take care of the information stored
43      * on that object.
44      *
45      * @var MidCOMDBAObject
46      */
47     var $object = null;
48
49     /**
50      * Creates the storage interface class, and initializes it to a given data schema.
51      * Specific storage implementation subclasses will need to expand this constructor
52      * to take care of linking to the right storage object, where applicable.
53      *
54      * @param midcom_helper_datamanager2_schema &$schema The data schema to use for processing.
55      */
56     function __construct(&$schema)
57     {
58         parent::__construct();
59
60         $this->_schema =& $schema;
61     }
62
63     /**
64      * This function will populate the $object member with a temporary object obtained
65      * by the MidCOM temporary object service.
66      *
67      * The code using this storage instance <b>must</b> take care of transitting this
68      * temporary object into future sessions (which means switching to another storage
69      * backend at that point).
70      *
71      * If the storage object is already populated, the method will exit silently.
72      *
73      * @see midcom_services_tmp
74      * @see midcom_core_temporary_object
75      */
76     function create_temporary_object()
77     {
78         if ($this->object === null)
79         {
80             $this->object = $_MIDCOM->tmp->create_object();
81         }
82     }
83
84     /**
85      * Stores a set of types to the configured storage object. This is done
86      * by subclass implementations, where this function serves as a request
87      * switch.
88      *
89      * Any types defined in the schema but not found in the passed type listing
90      * are ignored unless they are flagged as required, in which case
91      * generate_error is called.
92      *
93      * @param Array &$types A reference to an array of types matching the schema definition.
94      * @return boolean Indicating success.
95      */
96     function store(&$types)
97     {
98         foreach ($this->_schema->fields as $name => $type_definition)
99         {
100             if (! array_key_exists($name, $types))
101             {
102                 if ($type_definition['required'] == true)
103                 {
104                     $_MIDCOM->generate_error(MIDCOM_ERRCRIT, "Failed to process the type array for the schema {$this->_schema->name}: "
105                         . "The type for the required field {$name} was not found.");
106                     // This will exit.
107                 }
108                 else
109                 {
110                     continue;
111                 }
112             }
113             
114             if ($type_definition['readonly'])
115             {
116                 // Skip storage as we may raise exceptions if the field doesn't exist
117                 continue;
118             }
119
120             // Convert_to_storage is called always, the event handler can be used to manage
121             // non-storage-backend driven storage operations as well (mainly for the blob type)
122             $data = $types[$name]->convert_to_storage();
123             if ($type_definition['storage']['location'] !== null)
124             {
125                 if ($types[$name]->serialized_storage)
126                 {
127                     $data = serialize($data);
128                 }
129                 $this->_on_store_data($name, $data);
130             }
131         }
132
133         // Update the storage object last
134         if (! $this->_on_update_object())
135         {
136             debug_push_class(__CLASS__, __FUNCTION__);
137             debug_add('Failed to update the content object, last Midgard Error was: ' . mgd_errstr(), MIDCOM_LOG_WARN);
138             if (isset($php_errormsg))
139             {
140                 debug_add("Last PHP error was: {$php_errormsg}", MIDCOM_LOG_INFO);
141             }
142             debug_pop();
143             return false;
144         }
145
146         return true;
147     }
148
149     /**
150      * Override this function to implement the storage method for your backend.
151      * It has to store the given data to the schema field identified by the given
152      * name.
153      *
154      * @param string $name The name of the field to save to.
155      * @param mixed $data The data to save to.
156      */
157     function _on_store_data($name, $data)
158     {
159         die ('The function ' . __CLASS__ . '::' . __FUNCTION__ . ' must be implemented in subclasses.');
160     }
161
162     /**
163      * Loads a set of types to the configured storage object. This is done
164      * by subclass implementations, where this function serves as a request
165      * switch.
166      *
167      * Any types defined in the schema but not found in the passed type listing
168      * are ignored unless they are flagged as required, in which case
169      * generate_error is called.
170      *
171      * @param Array &$types A reference to an array of types matching the schema definition.
172      */
173     function load(&$types)
174     {
175         foreach ($this->_schema->fields as $name => $type_definition)
176         {
177             if (! array_key_exists($name, $types))
178             {
179                 if ($type_definition['required'] == true)
180                 {
181                     $_MIDCOM->generate_error(MIDCOM_ERRCRIT, "Failed to process the type array for the schema {$this->_schema->name}: "
182                         . "The type for the required field {$name} was not found.");
183                     // This will exit.
184                 }
185                 else
186                 {
187                     continue;
188                 }
189             }
190             if ($type_definition['storage']['location'] !== null)
191             {
192                 $data = $this->_on_load_data($name);
193                 if ($types[$name]->serialized_storage)
194                 {
195                     // Hide unserialization errors, but log them.
196                     $data = @unserialize($data);
197                     if (isset($php_errormsg))
198                     {
199                         debug_push_class(__CLASS__, __FUNCTION__);
200                         debug_add("Unserialization failed for field {$name}: {$php_errormsg}", MIDCOM_LOG_INFO);
201                         debug_pop();
202                     }
203                 }
204             }
205             else
206             {
207                 $data = null;
208             }
209
210             // Convert_from_storage is called always, the event handler can be used to manage
211             // non-storage-backend driven storage operations as well (mainly for the blob type)
212             $types[$name]->convert_from_storage($data);
213         }
214     }
215
216     /**
217      * Override this function to implement the storage method for your backend.
218      * It has to store the given data to the schema field identified by the given
219      * name.
220      *
221      * @param string $name The name of the field to load from.
222      * @return mixed $data The data which has been loaded.
223      */
224     function _on_load_data($name)
225     {
226         die ('The function ' . __CLASS__ . '::' . __FUNCTION__ . ' must be implemented in subclasses.');
227     }
228
229     /**
230      * This callback is invoked once the storage object has been completely updated with
231      * the information from all types. You need to store it to the database at this point.
232      *
233      * @return boolean Indicating success.
234      */
235     function _on_update_object()
236     {
237         die ('The function ' . __CLASS__ . '::' . __FUNCTION__ . ' must be implemented in subclasses.');
238     }
239
240     /**
241      * Checks whether the current user has the given privilege on the storage backend.
242      * If there is no valid storage backend, a can_user_do is performed. Subclasses
243      * may overwrite this method to incorporate for creation mode stuff.
244      *
245      * @param string $privilege The privilege to check against.
246      * @return boolean true if the user has the permission, false otherwise.
247      */
248     function can_do($privilege)
249     {
250         if ($this->object === null)
251         {
252             return $_MIDCOM->auth->can_user_do($privilege);
253         }
254         else
255         {
256             return $_MIDCOM->auth->can_do($privilege, $this->object);
257         }
258     }
259 }
260
261 ?>
Note: See TracBrowser for help on using the browser.