📜 ⬆️ ⬇️

CMS architecture. Data model Part 2

We continue the theme of the object data model. In this part, we will focus on the Data module, which is, in fact, an ORM system. For clarity, the work of the Data module with its help will create the contents of a simple site. Previous article: CMS Architecture. Data model Part 1.

The Data module consists of the Data, Object, Multy, Query classes and the Cond * class set. The module itself is a static class Data, the remaining classes are used to represent the data structures with which it works. To represent entities in the program code, the Object class is used. No matter what type of entity — the data class, the data object, or the relationship between them — for all Objects. The Multy class is used to associate with a set of entities, in particular, to represent multiple properties. The Query and Cond * classes are required to perform a search on the object model (in the database), subject to flexible conditions.

Reading entity


You can get an entity from a database by its identifier in the following way:

$obj = Object::Create(1); // 1

Instead of the new operator, the static Create () method is used. It checks the existence of an instance of the requested entity, perhaps the entity is already loaded from the database. If loaded, the Create () method will return a reference to its instance, otherwise the instance associated with the requested entity will first be created and then a reference to it will be returned.
')
After receiving the entity, it can be fully used, for example, to refer to its class and find out the system name.

echo $obj->getP( 'class' )->getA( 'sys_name' );

Notice that the loaded entity is a class, but the work is done with it as an object. The entity is loaded from the database on demand, that is, the actual access to the database occurs only when the first access to the properties or attributes of the entity, moreover, only those properties (entities with which the connection is made) that are used are loaded.

Perhaps you wondered if the structure could not be shortened to access the properties and attribute? Magic methods, optimization, stylization is a matter of time and the solution of some subtleties.

The object has properties (Property) and attributes (Attribute). Attribute is a scalar value. A property is a connection to another object, in fact, an object with which the connection is made. The relationship to class and the connection to inheritance are optimized — they are presented in the database as attributes, but by the logic of the data module they turn into properties.
To access the properties, use the getP ($ name) method, which returns the object with which it is connected. You can access the link itself using the getL ($ name) method — the link object will be returned.

In the above example, the class is accessed, but the connection with the class is not implemented by the object (because it is optimized), so the reference to the link to the class is meaningless - there is no object-link. The getA ($ name) method is used to read the attribute value by its name.

Entity loading is automatically initiated at the first access to any of its attributes or property. The load is automatically executed by the Load () method. To load an entity, its class is defined, the class inheritance hierarchy is determined. The classes are used to determine the tables from which the entity attributes are loaded. To load the properties, it is enough to directly refer to the link table and load all links whose “primary” attribute equals the identifier of the loaded entity. Only links are loaded. The objects referenced by the link are loaded according to the general principle - if their attributes or properties are used.

Create entity


For example, create an object of class “id”. The object will have only an identifier and a link to the class by which it is defined.

$new = Object::Create();
$new->setP( 'class' , Object::Create(1));
$new->Save();
Or abbreviated:
$new = Object::Create( null , Object::Create(1));
$new->Save();

Everything is very simple: an empty entity instance is created, a link to the class with identifier 1 is created, and the storage is performed. After that, a new entry appears in the “id” table. The attribute-identifier of the entity is created automatically by auto-increment of the key field of the table “id”.

Creating a class is exactly the same. For example, create a test class with the name “my” and the definition of the attribute “value”:

$new = Object::Create();
$new->setP( 'class' , Object::Create(2)); // , #2
// ,
// , ( )
$new->setP( 'extend' , Object::Create(1)); //
$new->setA( 'sys_name' , 'my' ); //
$new->setA( 'final' , 0); //
//
$new->setA_cl( 'value' , array( 'type' => 'varchar' , 'max' =>255)); //
$new->Save();

The attribute definition is reduced to specifying the parameters of the database table field. After saving, the table “my” will be automatically created with the fields “id” and “value” and an entry in the table “id” and “class” added, associated with the entity-class “my”

The attribute description is performed by the setA_cl method ($ name, $ params). Nothing complicated, just specify the name of the attribute and the parameters corresponding to the parameters of the field of the database table.

If you need to define a property, then the setP_cl method ($ name, $ class) creates a connection with the name $ name to the entity-class $ class. In this case, it is possible to clarify the attributes of the connection, by applying the getL_cl ($ name) method to the automatically created communication entity.

Now you can create an object of class "my". Suppose the created class “my” received the identifier 5.

$new_obj = Object::Create();<br>$new_obj->setP( 'class' , Object::Create(5)); <br>$new_obj->setA( 'value' , ' ' ); // <br>$new_obj->Save();<br>

Deleting an entity


Removing an entity is even easier:

$obj = Object::Create(6);
$obj->Delete();

First an instance of the deleted entity is created (the entity is not loaded from the database), then it is called
Delete () method.

When an entity is deleted, all its links are automatically deleted. If the connection is of the "consist" type (kind = 0), then the entity to which the link refers will be deleted. Delete the entity, which is part of another entity (type of connection = "consist"), will not work. Also, it will not be possible to delete a class if it is inherited by another class or there are entities of this class.

The current version of CMS Boolive is freely available. Information on the site
To test the code in the article, paste it into the file.
/modules/page/templates/view/root.php

The data module provides the three basic entities with the necessary logic that provides incredibly flexible possibilities for constructing an object model of any complexity.

Content modeling


Let's start modeling the site content. Create some simple classes to represent strings and numbers: string, long_string, text, integer, double. Each class defines one attribute “value” for values. Class «string» - to represent short strings of no more than 255 characters. "Long_string" - to represent a long term, restrictions on the length of no more than 20486 characters (20Kbytes). The class “text” is for very long lines of up to 65535 characters inclusive (64Kbytes). "Integer" - for integer signed numbers of 32 bits (-2147483648 ... +2147483647). “Double” - for real numbers (-1.7976931348623157e + 308 ... 1.7976931348623157e + 308). There is no need to represent other types of values ​​yet.

All five new classes inherit the base class “id”. They are determined by the class "class", from which they are classes. In the diagram (Fig. 1), not all attributes are displayed for entities - the identifier is duplicated in the header of the entity rectangle, the entity class is also indicated by its system name (“class”) and the attribute value “sys_name” in italic green.
PHP code to create 5 classes representing strings and numbers.

.
Figure 1. Main classes for representing strings and numbers.

Now you can create objects of any of the new classes. But we will deal with others. Add a definition of two properties to the class “class” and “link”. Defining two properties in the class “class”, we thereby add the corresponding properties to all classes: “id”, “class”, “link”, “string” and the rest, since they are objects of the class “class”. Also for the link class - all link objects will have properties in addition to the existing attributes.

So, we add the definition, for this we create a connection between the class “class” and the class “string” (Fig. 2. # 9). At the connection, we set the attribute values: connection type ("kind" = 0), power ("size" = 1), a sign of the mandatory existence of the property being defined for objects ("is_mandat" = 1). The remaining attributes are initialized automatically. Two connections are created, one for the class “string” and the other for the class “long_string”.
PHP code for defining properties in the class "class"

After each class will have the property "name" and "descript". The first property for class naming in Russian, the second for describing the purpose of the class. In fact, we have given the object model the ability to document ourselves. For example, there will be a link “create News” on the site, while the word “News” itself, and even the description of what news is or what is actually created will be meaningfully taken from the database, and not written in the design template or loaded from somewhere from the side.

Now we add the definition of two properties in the “link” class. These properties will be optional for links (“is_mandat” attribute = 0). The first property with the system name “label” will be used to name the connection in natural language, the second property to clarify the connection (properties of the object that owns the connection). Figure 2. # 11, # 12.
PHP code for defining properties in the "links" class

Created property definitions for relationships have the same meaning as properties for classes. Thanks to him, the object model, as if it will itself say: “the news has a title”. The object model is now able to describe itself and facilitate the creation of a convenient user interface.

Now it is necessary to create properties for classes and relationships whose presence has just been defined. Let's start with the links. Since the properties for the links are determined optional, we restrict ourselves to the naming of the links in the “class” and “link” classes. Figure 2. # 13 - # 20
PHP code for adding “label” properties on relationships that define properties of classes and relationships

Now let's deal with the classes. There are already 8 classes. Since the properties for classes are defined as required, it means that they must be created for each class. In fact, a normal title and description is added to each class. Figure 2.
PHP code to add the properties "name" and "descript" for all classes


Fig 2. Basic data classes and their description.

As can be seen from the diagram (Figure 2), each class has a name and description in Russian. All relationships between entities are objects, which can also be seen in the diagram. The objects of the lines are schematically simplified, the text in the nutria of the rectangle is the value of their only attribute “value”.

Now closer to the topic of site content. Let's create four classes for example. The first one is the class “content” (Material) with the properties “head” (Heading) and “text” (Text). This will be the simplest type of material for the site, which is suitable for news or articles. The “content” class is inherited from the “id” base class, and the “string” and “text” classes are used as properties. Figure 3. # 52 - # 63
PHP code to create a class Material

We demonstrate the possibilities of inheritance. We will create the comment class “comment” by inheriting it from the “content” class, from which it will already have the definition of the title property and the text. For comments, we consider them sufficient and nothing new in it will not be determined. Figure 3. # 64 - # 68.
PHP code to create a comment class

To categorize the site material, create a category category “category”. The class “category” inherits the base class “id”, so it does not have property definitions yet. For a category, a name is needed and its explanation is all the same properties with a similar purpose. A feature of categories is their hierarchical structure. To be able to create hierarchies from categories, each category must have a link to the parent category. This feature is provided by the “parent” property, in the definition it connects the class “category” with itself, which indicates: the parent for a category is a category. Figure 3. # 69 - # 82.
PHP code to create a class Category

And the last class to be created by us is the news class “news”. This class inherits the content class and adds new definitions for the comments property and the category. The “comments” property is multiple, because the news can have a lot of comments. Figure 3. # 83 - # 90.
PHP code to create a class News


Figure 3. Classes of the material and its categorization

All necessary classes are created. In a working CMS there will of course be many other classes and not just for presenting content. The goal now is to demonstrate the work of the Data module and the capabilities it provides for data management.

Finally, we create several content objects. Three categories, two news and two comments belonging to the same news. The second news without comment. The diagram clearly shows the created objects and their composite properties and properties of the "use" type. Figure 4.
PHP code for creating three categories, two news and two comments for the first news

,
Figure 4. Three categories, two news and two comments.

This is just an example of a content object model. Any element of the site can be represented as data objects: modules, blocks, users, groups, actions and rights to them - the possibilities are fantastic.

Now the question arises, how to work with all this? How, for example, get a list of news? What about conditions, such as news of a certain category? All of this functionality has already been implemented. The Query and Cond * classes were mentioned at the beginning of the article. By means of them search of entities is carried out. This will be discussed in the continuation of the article - in the third part.

Continued: Data Model. Part 3
Project website: boolive.ru

Source: https://habr.com/ru/post/53615/


All Articles