Tools For Better Developers

News: 2022 Jan 31 - Feb 18

2022 February News

5 months ago ∙ 3 minutes read

I came with an idea of much cleaner Osm Admin data class "markup", and more straightforward architecture, and I decided to give it a go in a separate experimental branch v0.2, and to see if it's viable.

After three weeks of implementation effort, I can say that it is viable, and it's so much better! And it's not a completely new effort, I mostly copy code from v0.1 and some parts of osmphp/framework:old_v4, and adapt it.

You can already define data classes using new markup, generate the database tables, and query it using new formula syntax. I really wanted to come with some UI working, but there wasn't enough time for that. It stays my priority for the next iteration.

More details:

Osm Admin v0.2.0

Diff

Getting Started Is So Much Easier!

The main idea of v0.2 is that data classes should work without any attributes. Actually, you can even start without any properties!

It's enough to extend the Record class, generate a database table for the class using osm migrate:schema command, and you are good to go:

class Product extends Record {
}

Immediately, you'll be able to manage products visually in the admin area, integrate them with other applications using the HTTP API, or implement some internal custom logic using the query(Product::class) syntax.

Of course, you can add your own custom properties, create explicit table columns for them, compute their value using formulas, specify UI control, and many other things. Properties can be scalars, objects, arrays, or references to other records.

For more details, read the blog post.

Standard Properties

Classes inherit two properties from the Record class:

  • id - Unique auto-incremented object ID. It's used for creating relationships between objects, and for object selection in a grid.
  • title - Object title. It's used for in various places of the admin area, for example, while displaying the object in dropdown option list, or in the page title of an edit form.

Formula Syntax

The query syntax introduces formulas - SQL-like expressions that you can use in SELECT, WHERE, ORDER BY (and later GROUP BY) clauses:

$products = query(Product::class)
    ->where("id IN (1, 2, 3)")
    ->where("title LIKE '%dress%'")
    ->get('id', 'title');

You may ask why inventing the new syntax if SQL is already good at what it does. And it's a great question. The main reason for introducing formulas lies in the near future.

You'll be able to specify how a property is computed from other properties of its object, and from the properties of the related objects. For example, consider a hierarchical category object tree where child categories "inherit" their values from the parent category:

/**
 * @property ?Category $parent #[Explicit]
 * @property ?int $level #[Computed("(parent.level ?? -1) + 1")]
 * @property ?string $id_path #[
 *      Computed("(parent.id_path IS NOT NULL ? parent.id_path + '/' : '') + id"),
 * ]
 */
class Category extends Record {
}     

And raw SQL syntax is not a good fit for this use case, mainly because there is no good way to implicitly join related tables for expressions like parent.level, or parent.parent.level, and to integrate them into more complex expressions like (parent.level ?? -1) + 1".

Syntactic Sugar

There is also some syntax sugar in formula queries compared to SQL:

  1. All constants in a formula are converted to SQL bindings. For example, id IN (1, 2, 3) formula is converted into id IN (?, ?, ?) raw SQL.
  2. Instead of COALESCE(property1, property2, property3), write property1 ?? property2 ?? property3.
  3. Instead of IF(id = 1, title, status), write id = 1 ? title : status.

SQL Compatibility

Other formula syntax will be as close to standard SQL as possible, so you don't have to learn a new language.

New Architecture

In v0.1, there were over 10 modules, each responsible for a single concept. It's been a nice try, but in reality, these concepts were not as independent, and adding new features faced increasing resistance caused by unnecessary complexity.

In v0.2, the whole architecture is a lot more simplified:

New Architecture

As you can see, there are only three modules left:

  • Schema - table/class/property definitions
  • Queries - well, for querying data
  • Ui - for managing data visually, and through the API

Check more diagrams for a detailed look.

Roadmap

As I'm heading to some minimum Osm Admin user interface - one property, one data type, one UI control type - a lot of things are left unfinished.

At some point, they will! In order to keep track of them, they are listed in the product roadmap.

osm.software Website v0.4.8

Diff

Two new blog posts have been written about Osm Admin:

Also, Osm Admin v0.2 documentation added. As it fills in, it'll become more and more useful.

Osm Core v0.10.18

Diff

Better Inheritance Reflection

Navigate inheritance hierarchies easier using new parent_class_name, parent_class, and child_class_names properties of the Class_ reflection:

global $osm_app;

echo $osm_app->classes[App::class]->parent_class->name;
// Osm\Core\Object  

Fixes

The osmc and gulp provide an informative error message about unfinished @property definitions like this:

/**
 * @property
 */
class Foo extends Object_ {
}

I'm just getting started, and a lot more features are yet to come!

If you've enjoyed reading this, follow me on Twitter and be the first to know.