User Tools

Site Tools


datarecord_class

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
datarecord_class [2020/08/07 11:23] – [store_in_database] sahldatarecord_class [2024/02/14 15:51] (current) – [References between Datarecords and save deletes] sahl
Line 1: Line 1:
 ====== Datarecord class ====== ====== Datarecord class ======
  
-The Datarecord class is one of the core classes of Platform, as it provides a highly flexible object which can easily be stored in the database.+The Datarecord class is one of the core classes of Platform, as it allows you to create highly flexible objects that are easily stored in database. 
  
 You can look for the Templateclass class which provides a blueprint for your own Datarecord class and can easily be altered to your own purpose. The Templateclass is meant as an example file, so you shouldn't subclass it, but just copy and rename it. You can look for the Templateclass class which provides a blueprint for your own Datarecord class and can easily be altered to your own purpose. The Templateclass is meant as an example file, so you shouldn't subclass it, but just copy and rename it.
Line 7: Line 7:
 ===== Quick start ===== ===== Quick start =====
  
-There'three steps to get a new Datarecord class up and running.+The most basic Datarecord class looks like this: 
 +<code php> 
 +class Templateclass extends Datarecord { 
 +     
 +    protected static $database_table = 'DATABASE TABLE'; 
 +    protected static $delete_strategy = self::DELETE_STRATEGY_BLOCK; 
 +    protected static $location = self::LOCATION_INSTANCE; 
 +     
 +    protected static $depending_classes = [ ]; 
 +    protected static $referring_classes = [ ]; 
 + 
 +    protected static $structure = false; 
 +    protected static $key_field = false; 
 +    protected static $title_field = false; 
 +     
 +    protected static function buildStructure() { 
 +        static::addStructure([]); 
 +        parent::buildStructure(); 
 +    } 
 +
 +</code> 
 + 
 +From here there is three steps to get it up and running.
  
 ==== 1. Database table ==== ==== 1. Database table ====
 +
 +We must decide for the database table name, which is done by overwriting the ''$database_table'' variable.
  
 <code php> <code php>
-protected static $database_table = 'DATABASE TABLE';+protected static $database_table = 'my_database_table';
 </code> </code>
- 
-Alter the line above to select which table you want to store objects of this type into. (Don't create the table). 
  
 ==== 2. Object definition ==== ==== 2. Object definition ====
  
-Overwrite the buildStructure method to define which fields you want your object to consist of (see below).+Now we must define which fields our Datarecord object consists of. This is done by adding the appropriate [[Class Type|types]] to the object by calling the addStructure function with an array of types and then calling ''buildStructure()''This is an example of a simple structure for holding an address book consisting of a name, a phone number and an email:
  
-==== 3. Build table ====+<code php> 
 +    protected static function buildStructure() { 
 +        static::addStructure([ 
 +            new KeyType('contact_id'), 
 +            new TextType('full_name', 'Full name', ['is_required' => true, 'is_title' => true]), 
 +            new TextType('phone_number', 'Phone number'), 
 +            new EmailType('email', 'Email'
 +        ]); 
 +        parent::buildStructure(); 
 +    } 
 +</code>
  
-Ensure to add the ''ensureInDatabase()'' function of your new class to a suitable place in your codewhich would most typically be the ''initializeDatabase()'' function in your subclass of [[instance_class|Instance.]]+The first parameter is the desired database field, the next is the human readable field name and the last are specific options for the selected type.
  
-Now your object is ready to use. +==== 3Build table ====
- +
-===== Object structure ===== +
- +
-You design the object by adding a structure to it, in the ''buildStructure()'' functionThe structure is defined by an array of arrays as defined below and is passed to the ''addStructure()'' function. +
- +
-Each element in the outer array represents a field and is hashed by the field name, while the inner array contains the field definition. The field definition contains the following fields: +
- +
-==== label ==== +
- +
-The label is the human readable name of the field. +
- +
-==== fieldtype ==== +
- +
-The fieldtype defines the possible content of the field and should refer to one of the following constants: +
- +
-^FIELDTYPE_KEY               | The primary key which is an integer number and automatically assigned. Exactly one field must be of the FIELDTYPE_KEY type.| +
-^FIELDTYPE_ARRAY             | An array of values.| +
-^FIELDTYPE_BIGTEXT           | A text of up to 16 mil. characters.| +
-^FIELDTYPE_BOOLEAN           | A boolean value.| +
-^FIELDTYPE_CURRENCY          | A currency value.| +
-^FIELDTYPE_DATETIME          | A datetime.| +
-^FIELDTYPE_ENUMERATION       | A enumeration. You need the enumeration property.| +
-^FIELDTYPE_INTEGER           | An integer number.| +
-^FIELDTYPE_FILE              | A reference to a file. You need the folder property.| +
-^FIELDTYPE_FLOAT             | A floating point number.| +
-^FIELDTYPE_OBJECT            | A complex object.| +
-^FIELDTYPE_PASSWORD          | A password, which can only be written or checked.| +
-^FIELDTYPE_REFERENCE_SINGLE  | A reference to another Datarecord object. You need to specify the class in the foreignclass property.| +
-^FIELDTYPE_REFERENCE_MULTIPLE| A reference to several other Datarecord objects. A reference to another Datarecord object. You need to specify the class in the foreignclass property.| +
-^FIELDTYPE_REFERENCE_HYPER   | A reference to another Datarecord object, which can be of a different class from object to object. | +
-^FIELDTYPE_TEXT              | A text of up to 255 characters.| +
- +
- +
- +
-==== Additional properties ====+
  
-Each field can have the following additional properties+To ensure the table is build in the database and ready for use, we need to call the ''ensureInDatabase()'' function of our new class, which will automatically build an appropriate SQL table. If you later extend or modify the structure of your class, just call this function again to modify the database to match your modifications. 
  
-^enumeration|If the field is an enumeration, this should be the enumeration array, where the keys are the constants and the values are the visible values.| +The natural place to call this function is in the ''initializeDatabase()'' function in your subclass of [[instance_class|Instance.]]
-^folder|If the field is a file field, this should specify which folder we store these files into.| +
-^foreign_class|If the field is a reference to another class, this property should be the name of this class.| +
-^form_size|Provides a hint to the form generator about the size of this field| +
-^calculations|Determine what calculations should be performed on a remote object when this object is changed. See later.| +
-^default_value|The default value of this field.| +
-^invisible|A field of this type is invisible and cannot be viewed or edited by the user.| +
-^is_title|If this is true, then this field is considered the title for the object.| +
-^key|Indicates if this field should have a database key for improved performace. See below.| +
-^required|The field is required, meaning that a form field representing this field will be mandatory.| +
-^readonly|This field is readonly, which means it doesn't appear in forms.| +
-^searchable|Indicates if this field is searchable. See below. Only work on text-based fields.| +
-^store_in_database|Indicate if the field should be stored in the database. Defaults to true. See below.| +
-^store_in_metadata|Each object contains a metadata field which is an array stored in a single database field (as json). If you specify this property, then the field will be saved into the metadata instead of having its own database field. This is useful for limiting the number of database fields, but makes the field unsuitable for searching or other high-performance operations.| +
-^table|This field defines how the field is shown in tablesSee constants below.| +
-^tablegroup|If true tables will group by this field.| +
-==== table constants ====+
  
-^COLUMN_VISIBLE | Show the column (but allow the user to hide it). This is the default setting if no value is passed.| +After thisyour object is ready to use.
-^COLUMN_HIDDEN| The column is hidden by defaultbut the user can select to show it.| +
-^COLUMN_INVISIBLE| The column is hidden and cannot be selected to show.|+
  
-==== store_in_database ==== +===== Basic object usage (read / write) =====
  
-If this is set to false, the field will not be read or written to the database, but still be available. This can be used for calculated fields, where you then have to overwrite the getValue method in order to display data. Example: If you have two fields first_name and last_name, and also want field full_name, you can implement full_name as a field not stored in the database.+A Datarecord is created just like regular object
  
 <code php> <code php>
-protected static function buildStructure() { +$contact new Contact();
-    $structure array( +
-        'person_id' => array( +
-            'invisible' => true, +
-            'fieldtype' => self::FIELDTYPE_KEY +
-        ), +
-        'first_name' => array( +
-            'label' => 'First name', +
-            'fieldtype' => self::FIELDTYPE_TEXT +
-        ), +
-        'last_name' => array( +
-            'label' => 'Last name', +
-            'fieldtype' => self::FIELDTYPE_TEXT +
-        ), +
-        'full_name' => array( +
-            'label' => 'Full name', +
-            'fieldtype' => self::FIELDTYPE_TEXT, +
-            'store_in_database' => false +
-        ), +
-    ); +
-    self::addStructure($structure); +
-    parent::buildStructure(); +
-+
- +
-// We override this to make a special handling of the full_name field. +
-// For all other fields we just call the parent function. +
-public function getRawValue($field) { +
-    switch ($field) { +
-        case 'full_name': +
-            return $this->first_name.' '.$this->last_name; +
-        default: +
-            return parent::getRawValue($field); +
-    } +
-}+
 </code> </code>
  
-**Pro tip:** Only use this for very light calculations with information already available on the object. It shouldn't be used for fields requiring heavy calculations or database lookup, as this can lead to poor performance. +The following two are equivalent and are used to assign value to a field in the object:
- +
-===== Basic object usage ===== +
- +
-The object is created just like regular object. +
- +
-<code php> +
-$user = new User(); +
-</code> +
- +
-To set a field use one of the following, which is equivalent:+
  
 <code php>  <code php> 
-$user->setValue('username', 'Michael Sahl'); +$contact->setValue('full_name', 'Michael Sahl'); 
-$user->username = 'Michael Sahl';+$contact->full_name = 'Michael Sahl';
 </code> </code>
  
-To read a value use one of these:+These fields can be read back using one of the following (where both are equivalent):
  
 <code php> <code php>
-$username = $user->getValue('username'); +$full_name = $contact->getRawValue('full_name'); 
-$username = $user->username;+$full_name = $contact->full_name;
 </code> </code>
  
-There are more ways to read values from an object. This will be covered further down. +Up until now we have only had the object in memory, but we can store it in the database by using the ''save()'' function:
- +
-To save an object to the database:+
  
 <code php> <code php>
-$user->save();+$contact->save();
 </code> </code>
  
-This will automatically fill in the object key field (the field with type FIELDTYPE_KEY) with a new ID from the databaseif it is the first time being saved. In addition it will only save the object is something have actually changed (which can be overwritten by passing true as the first parameter to //save// which will always save).+This will save the object in the database (assuming we have built the corresponding table using the ''ensureInDatabase()'' function) and also automatically fill the key field with the assigned ID from the database if this is the first time the object is saved.
  
-To load an object from the database, using an ID, use one of the following:+We can retrieve the key:
  
 <code php> <code php>
-$user->loadForRead($id); +echo $contact->contact_id;
-$user->loadForWrite($id);+
 </code> </code>
  
-Loading an object for read, doesn't allow to save it. Loading it for write will block the object so another process cannot load it for write before this process is finished with it. This is to ensure that two processes doesn't change the same object at the same time. When saving an object it is switched back to read modeunless explicitly held open by passing true as the second parameter:+If we need to retrieve this object at a later time, we can just use this ID in one of the following ways:
  
 <code php> <code php>
-$user->save(false, true); +$contact = new Contact(); 
-</code>+$contact->loadForRead($id);
  
-If an object is opened for writing, but one decides not to save it, it can be unlocked like this:+// OR 
  
-<code php> +$contact = new Contact(); 
-$user->unlock();+$contact->loadForWrite($id);
 </code> </code>
  
-...which also will switch it to read mode.+When loading objects from the database we can both load them in a read context and a write context.
  
-An object can be deleted from write mode by calling ''delete'', but one should check if we can delete it, by calling ''canDelete'' first:+Loading an object for read prevents you from saving it again, and should only be used if you are interested in retrieving information from the object without changing it.  
 + 
 +Loading an object for write will lock the object, so no other process can change it, before we are finished with it. This is to ensure that two processes doesn't change the same object at the same time thereby having one process overwriting the changes from the other process.  
 + 
 +All objects locked this can be unlocked in one of three ways: 
 + 
 +  - By saving it. The object will be switched back into read mode afterwards. 
 +  - By calling the ''unlock()'' function. This will switch the object back to read mode without saving changes. 
 +  - At the end of script execution. 
 + 
 +===== Deleting objects ===== 
 + 
 +An object which have been saved to the database can be deleted by opening it for write and calling the ''delete()'' function:
  
 <code php> <code php>
-if ($user->canDelete()) $user->delete();+$contact->delete();
 </code> </code>
  
 ===== More about values ===== ===== More about values =====
  
-Values in the datarecord object can be accessed in four different modes.+Values in the Datarecord objects can accessed in different waysUp until now we have only accessed the //raw// values, which are the programmatically or technical values of the field. But there are several other ways to access field values. For example we could imagine a telephone number. The raw value could be +15551234567, but when we display it in our application, we would maybe like to include a html tel-type link and display it with proper spacing such as:
  
-^Mode^Function^Explanation^ +<code html> 
-|RENDER_RAW|getRawValue()|This is the "rawvalue, meaning the technical value of the field. If it is reference, this is the ID to the foreign data.| +<a href="tel:+15551234567">+1 555 1234567</a> 
-|RENDER_FULL|getFullValue()|This is the display value, meaning the value to show to the end user. This is typically styled with html.| +</code>
-|RENDER_TEXT|getTextValue()|This is the display value, but suited for a text-only context, meaning that it isn't styled with html.| +
-|RENDER_FORM|getFormValue()|This is the value as suited to pass into a proper form field.|+
  
-The basic functions to get and set values are ''setValue'' and ''getValue'', and the datarecord also supports object notation to set and get values.+Or maybe we would use it in a text email, where html wasn't allowed but we would still like the nice spacing such as:
  
-<code php> ++1 555 1234567
-$user->setValue('name', 'Don Holmes'); +
-// is equal to: +
-$user->name = 'Don Holmes';+
  
-$name = $user->getValue('name'); +Datarecord provides for all of this by calling the correct function to get the value.
-// is equal to+
-$name = $user->name; +
-</code>+
  
-Prdefault getValue return raw values, but this behaviour can be modified by calling ''setDefaultRenderMode'' which can select another type to return from getValue.+^function^result^example^ 
 +|getRawValue()|Get the technical value used when programming|+15551234567| 
 +|getFullValue()|Get the value for display in a browserMay include HTML.|<a href="tel:+15551234567">+1 555 1234567</a>
 +|getTextValue()|Get the value for display in a text where HTML isn't allowed.|+1 555 1234567| 
 +|getFormValue()|Get the value compatible with a fitting form field.|| 
 +|getTableValue()|Get the value for displaying in a table.|| 
 +|getLogValue()|Get the value for displaying in a log file.||
  
 ===== Object title ===== ===== Object title =====
  
-datarecord object is considered to have a title, which is the human-readable way the object is presented when referred. The most simple way to assign a title is to just set the ''is_title'' property to true on a field. For a more complex way, one can also overwrite the getTitle function.+Datarecord object is considered to have a title, which is the human-readable way the object is presented when referred from other places. The most simple way to assign a title is to just pass the ''is_title'' property to the Type of the field containing the titleIf the title is more complex and depends on information from several fieldsthen one can also overwrite the ''getTitle()'' function. 
 ===== Convenience functions ===== ===== Convenience functions =====
  
 ==== Getting a form ==== ==== Getting a form ====
  
-With a properly formed field definition, one can get a form for editing the object by just calling ''getForm()''. This will return a [[form_class|Form]] object ready to use.+One can get a form for editing the object by calling ''getForm()''. This will return a [[form class|Form]] object ready to use.
  
-The form will contain all editable fields in the same order that they are defined in the ''buildStructure''-function+The form will contain all editable fields in the same order that they are defined in the ''addStructure''-function.
- +
-To place fields side-by-side, you can use the //form_size// property when defining the field. The property takes a percentage value, which dictates how much of the line the field should take up. As long as the line doesn't fill up, fields will be placed beside each other, so two fields with a size of 50% each, will be placed beside each other.+
  
 If one needs javascript to get the form to behave, then set the ''$edit_script'' variable of the class to point to the javascript. In HTML the form will have an ID of //[class_name]_form// If one needs javascript to get the form to behave, then set the ''$edit_script'' variable of the class to point to the javascript. In HTML the form will have an ID of //[class_name]_form//
Line 229: Line 171:
 ==== Complete edit interface ==== ==== Complete edit interface ====
  
-Calling the ''renderEditComplex($parameters)'' function will render a complete interface which will list all objects of this type, and allow the user to create, edit and delete these objects. The parameters are passed on to the [[table_class|Table]] listing the objects and can be used to extend functionality+Calling the ''renderEditComplex($parameters)'' function will render a complete interface which will list all objects of this type, and allow the user to create, edit and delete these objects.
  
-===== References between Datarecords =====+Also see [[EditComplex class]]
  
-It is easy to relate Datarecords to each other. To link a Datarecord to another datarecord add a field of field type ''FIELDTYPE_REFERENCE_SINGLE'' or ''FIELDTYPE_REFERENCE_MULTIPLE''. The first will refer to a single object from the other datarecord class and the second will refer to multiple objects. When using these fields, you will also need to specify the ''foreignclass''-property which should be the full class name of the foreign datarecord class.+===== References between Datarecords and safe deletes ===== 
 + 
 +Some field types allows the linkage to other Datarecord object for example the [[SingleReferenceType class]] or the [[MultiReferenceType class]]. The first will refer to a single object from another datarecord class and the second will refer to multiple objects. When using these fields, you will also need to specify which other class you want to point to.  
 + 
 +If you extended the contact person example above, you could create a separate Datarecord class for the phone numbers and then make these phone numbers reference the contact person. In that way you can register several numbers to each contact person. 
 + 
 +This could be an example of such... 
 + 
 +CONTINUE FROM HERE
  
 You will also need to go to the foreign datarecord class and add the class name of this datarecord class to either the ''$referring_classes'' array or the ''$depending_classes'' array. This ensures that the foreign class is aware of the connection. See the chapter about deleting data for an explanation between the two arrays and see the section //Integrity check// below, for an easy way to check if references are configured correctly. You will also need to go to the foreign datarecord class and add the class name of this datarecord class to either the ''$referring_classes'' array or the ''$depending_classes'' array. This ensures that the foreign class is aware of the connection. See the chapter about deleting data for an explanation between the two arrays and see the section //Integrity check// below, for an easy way to check if references are configured correctly.
Line 240: Line 190:
  
 It is possible to use references with non-datarecord classes, as long as these classes implements the ''DatarecordReferable'' interface. It is possible to use references with non-datarecord classes, as long as these classes implements the ''DatarecordReferable'' interface.
 +
 ==== Deleting data and references ==== ==== Deleting data and references ====
  
-When deleting data, a system is in place for checking that no references are left to the deleted objectThere are two strategies available, which can be used by setting the ''$delete_strategy'' static variable in the datarecordbut before explaining these strategies, it's important to understand the two different class references we have.+Platform has a system in place to handle references when deleting data, so that we are not leaving dangling references all around the database. 
 + 
 +In order for this system to workone need to indicate which objects are referring the current object and that can be done by adding these foreign classes to one of the two arrays ''$referring_classes'' or ''$depeding_classes''
 + 
 +Adding it to ''$referring_classes'' indicates that the foreign object just refers this objectso if this object is deletedthe reference in the foreign object will be removed (set to 0). 
 + 
 +Adding it to ''$depending_classes'' indicates that the foreign object depends on this object, and cannot exist without it. That means that if this object is deleted, all foreign objects referring this object will also be deleted.
  
-In order for the delete system to function correctly, it is important that all classes that refers this class is mentioned in either the ''$referring_classes'' array or the ''$depending_classes'' array.+This logic is nested, so deleting an object can initialize a chain reaction of other deletions and references being removed, keeping your data without dangling references.
  
-Classes in the ''$referring_classes'' array should be classes, where the objects can refer this class but also can exist without such a reference. In a job database, we can have a class representing jobs and a class representing candidates. We can have a relation from a candidate to a job, to represent that the candidate is interested in the job. If the job then is deleted, we will still keep the candidate. Therefore we would put the candidate class in the ''$referring_classes'' array of the job class, to indicate that if the job is deleted, we should just remove the reference from the candidate, but otherwise keep the candidate object.+=== Delete strategies ===
  
-In opposition, the ''$depending_classes'' array should be classes, where the objects that refers this class cannot exist without such a reference. In a car database, we can have a class representing a car brand and another class representing the car model. We would have a relation from the model to the brand, but if the brand is deleted it wouldn't make sense to keep the models referring this brand, so therefore we would add the model class to the ''$depending_classes'' array in the brand class, to indicate that if brand is deleted, we should also delete all models referring to the brand.+Sometimes you don't want to delete an object if it is referred by anything else. You can handle this by setting a delete strategy.
  
-And now to the strategies:+There are three possible delete strategies:
  
 <code php> <code php>
Line 256: Line 213:
 </code> </code>
  
-This is the default strategy and this will prevent deletion of a datarecord if it is still references by other objects in the ''$referring_classes'' array. This will make ''canDelete'' return an error message if there are still objects referring the queried object, and will likewise prevent ''delete'' from deleting anything as long as such references exists, except if the ''$force_purge'' parameter is set to true, which will force the other delete strategy no matter what.+This is the default strategy and this will prevent deletion of a Datarecord, if it is still references by other objects in the ''$referring_classes'' array. This will make ''canDelete'' return an error message if there are still objects referring the queried object, and will likewise prevent ''delete'' from deleting anything as long as such references exists, which will force the other delete strategy no matter what. Please note that objects in the ''$depending_classes'' aren't considered in this regard. 
 +It is possible to specify the ''$force_purge'' parameter on the delete command, which will then switch to the next delete strategy.
  
 <code php> <code php>
Line 265: Line 223:
  
 When using this strategy, a call to ''canDelete'' will return true even though other objects references this object. When using this strategy, a call to ''canDelete'' will return true even though other objects references this object.
 +
 +<code php>
 +self::$delete_strategy = self::DELETE_STRATEGY_DO_NOTHING
 +</code>
 +
 +This strategy will delete the current object, but will not affect any referring or depending objects. This can only be used, when working with //soft deletion//. See below.
 +
 +==== Soft deleting objects ====
 +
 +Sometimes it can make sense to keep the database record after deleting an object, for example if you are synchronising  data to another system, and therefore needs to keep track on what you deleted.
 +
 +To add soft deletion to an object override the ''$delete_mode'' variable with one of these two options:
 +
 +<code php>
 +protected static $delete_mode = Datarecord::DELETE_MODE_EMPTY;
 +</code>
 +
 +This will add a field //is_deleted// to the datarecord object, and when the object is deleted, all fields will be emptied except the primary key, the create date and the last update date, and //is_deleted// will be set to 1.
 +
 +<code php>
 +protected static $delete_mode = Datarecord::DELETE_MODE_MARK;
 +</code>
 +
 +This will do exactly the same as above, except that no fields are emptied, so when deleting the object, it will remain in the database, but have the //is_deleted// field updated to 1.
 +
 +
 +Remember to ''ensureObjectInDatabase()'' after doing either of these to build the //is_deleted// field.
  
 ===== Copying objects ===== ===== Copying objects =====
Line 299: Line 284:
 ==== Pr. object calculations ==== ==== Pr. object calculations ====
  
-To do the calculation object by object, overwrite the ''doCalculation'' function. The object will automatically be saved afterwards, so the function just needs to perform the calculation.+To do the calculation object by object, overwrite the ''doCalculation'' function. The object passed will be in write mode and will automatically be saved afterwards, so the function just needs to perform the calculation.
  
 <code php> <code php>
Line 350: Line 335:
 Datarecords supports database keys for improved performance. To add a key to a field simply set the //key//-property to true. Datarecords supports database keys for improved performance. To add a key to a field simply set the //key//-property to true.
  
-To make a key spanning more than one field, instead set the //key//-property to the name(s) of the additional fields, separating field names by commas.+To make a key spanning more than one field, instead set the //key//-property to the name(s) of the additional fields, separating field names by commas. The current field will be first in the multiple key, followed by the fields mentioned.
  
 A call to ''ensureInDatabase()'' will build the appropriate keys. A call to ''ensureInDatabase()'' will build the appropriate keys.
Line 370: Line 355:
 will find all objects containing the word "red" and the phrase "hairy cat" in one or several of the searchable fields. will find all objects containing the word "red" and the phrase "hairy cat" in one or several of the searchable fields.
  
-Output of the function defaults to a [[datarecordcollection_class|DatarecordCollection]] but can be altered to be a simple array or output suited for the [[field_class|FieldDatarecordcombobox]] field type.+Output of the function defaults to a [[collection_class|Collection]] but can be altered to be a simple array or output suited for the [[field_class|FieldDatarecordcombobox]] field type.
  
 ==== Searching with SQL ==== ==== Searching with SQL ====
  
-It is possible to query the database directly, and a good way to do that is using the ''getCollectionFromSQL($sql)'' function. Just be sure to always //SELECT *// from the proper table. This will add all the found records to a [[datarecordcollection_class|DatarecordCollection]] and return it.+It is possible to query the database directly, and a good way to do that is using the ''getCollectionFromSQL($sql)'' function. Just be sure to always //SELECT *// from the proper table. This will add all the found records to a [[collection_class|Collection]] and return it.
  
 <code php> <code php>
Line 390: Line 375:
 // Check if we are allowed to create a new instance of this object. // Check if we are allowed to create a new instance of this object.
 Class::canCreate(); Class::canCreate();
 +
 +// Check if we are allowed to copy objects of this class (in general).
 +Class::isCopyAllowed();
 +
 +// Check if we are allowed to copy this object.
 +$object->canCopy();
  
 // Check if we are allowed to edit this object. // Check if we are allowed to edit this object.
datarecord_class.1596799413.txt.gz · Last modified: 2020/08/07 11:23 by sahl

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki