beecubu/php-foundation-core

Main package of PHP Object Foundation Framework.

Maintainers

Package info

bitbucket.org/beecubu/php-foundation-core

pkg:composer/beecubu/php-foundation-core

Statistics

Installs: 259

Dependents: 7

Suggesters: 0

v3.7.0.1 2026-03-17 10:40 UTC

README

Core package for PHP Object Foundation. This is the base used by the rest of the framework libraries. It provides:

  • A strict property system (Objectum) with typed properties and validation.
  • Serialization and JSON export/import (Serializable) with custom hooks.
  • Enum utilities (Enum), property definitions (Property), and serialization helpers.
  • Common tools: date/time utilities and formatters.

Requirements

  • PHP 7.1+
  • ext-openssl
  • ext-json

Installation

composer require beecubu/php-foundation-core

Key Concepts

Objectum (Typed Properties)

Define properties with types and access rules:

<?php

use Beecubu\Foundation\Core\Objectum;
use Beecubu\Foundation\Core\Property;

class User extends Objectum
{
    protected function properties(): void
    {
        $this->properties += [
            'name'   => [Property::READ_WRITE, Property::IS_STRING],
            'age'    => [Property::READ_WRITE, Property::IS_INTEGER],
            'active' => [Property::READ_WRITE, Property::IS_BOOLEAN],
        ];
    }
}

$u = new User();
$u->name = 'Ada';
$u->active = 'yes';

Enums

use Beecubu\Foundation\Core\Enum;

class Status extends Enum
{
    public const Draft = 'draft';
    public const Sent = 'sent';
}

Use enums in properties with validation:

use Beecubu\Foundation\Core\Property;

$this->properties += [
    'status' => [Property::READ_WRITE, Property::IS_ENUM, Status::class],
];

Serializable

Serializable extends Objectum and adds JSON/RawData serialization with custom hooks and property filtering.

<?php

use Beecubu\Foundation\Core\Serializable;
use Beecubu\Foundation\Core\Property;

class Article extends Serializable
{
    protected function properties(): void
    {
        parent::properties();
        $this->properties += [
            'title'   => [Property::READ_WRITE, Property::IS_STRING],
            'content' => [Property::READ_WRITE, Property::IS_STRING],
        ];
    }
}

$a = new Article();
$a->title = 'Hello';

$json = $a->json();        // stdClass
$raw = $a->rawData();      // stdClass

$copy = Article::instanceWithJson($json);

Encrypted Strings

If a property is Property::IS_STRING_ENCRYPTED, values are stored encrypted in raw data. In JSON, the framework exports them as an EncryptedStringProperty object with kind, encoding, and value.

$this->properties += [
    'secret' => [Property::READ_WRITE, Property::IS_STRING_ENCRYPTED],
];

Example JSON shape:

$json = $article->json();

$json->secret->kind;      // encrypted-string
$json->secret->encoding;  // base64
$json->secret->value;     // base64 payload

When importing from JSON:

  • If secret is a string, it is treated as plain text and encrypted.
  • If secret is an object, it is treated as an EncryptedStringProperty.

Object Auto-Initialization

By default, IS_OBJECT properties are auto-created when first accessed (if no value is set). You can disable this globally:

Beecubu\Foundation\Core\Objectum::$CreateObjectPropertiesOnGet = false;

On-Demand References

SerializableProperty::CREATE_ON_DEMAND_BY_ID allows lazy-loading related objects by id.
Important: the referenced class must implement protected static function instanceByRawDataId($id) or lazy loading will fail.
This method is called by the serialization layer when a property is accessed and only an id is available. The default implementation throws an exception, so each on-demand class must provide its own factory.

use Beecubu\Foundation\Core\SerializableProperty;

$this->properties += [
    'author' => [Property::READ_WRITE, Property::IS_OBJECT_NULLABLE, Author::class, SerializableProperty::CREATE_ON_DEMAND_BY_ID],
];

Example implementation:

class Author extends Serializable
{
    // properties()...

    protected static function instanceByRawDataId($id)
    {
        // Fetch from persistence layer by id and return an Author instance.
        // Example: return AuthorRepository::findById($id);
    }
}

Tools

Helpers

use Beecubu\Foundation\Core\Tools\Helpers;

Helpers::empty($value); // Better empty() for framework objects

Formatters

use Beecubu\Foundation\Core\Tools\Formatters\NumberFormatter;
use Beecubu\Foundation\Core\Tools\Formatters\DateFormatter;
use Beecubu\Foundation\Core\Tools\Formatters\StringFormatter;
use Beecubu\Foundation\Core\Tools\Formatters\PluralsFormatter;

NumberFormatter::numberToString(1234.56, 'en'); // "1,234.56"
DateFormatter::dateToString(new DateTime(), 'en');
StringFormatter::utf82iso('àéí');
PluralsFormatter::plural('day', 2, 'en'); // "days"

DateTime Helper

use Beecubu\Foundation\Core\Tools\DateTime;

$dt = new DateTime('@1717352123'); // respects php.ini timezone

Custom Properties (Serialization Hooks)

Serializable lets you override how specific properties are imported/exported by defining custom flags in customProperties().
The flags are defined in Beecubu\Foundation\Core\CustomProperty and control:

  • When the hook runs: import, export, or both
  • Which mode: JSON, RawData, or both

Typical pattern:

use Beecubu\Foundation\Core\CustomProperty;

class Report extends Serializable
{
    protected function properties(): void
    {
        parent::properties();
        $this->properties += [
            'status' => [Property::READ_WRITE, Property::IS_STRING],
            'secret' => [Property::READ_WRITE, Property::IS_STRING],
        ];
    }

    protected function customProperties(): void
    {
        $this->customProperties += [
            // Only transform when exporting to JSON
            'status' => CustomProperty::ON_EXPORT | CustomProperty::ON_JSON_MODE,
            // Only transform when importing from RawData
            'secret' => CustomProperty::ON_IMPORT | CustomProperty::ON_RAW_MODE,
        ];
    }

    protected function exportCustomProperty(string $property, $value, bool $rawDataMode, ?array $fields = null, bool $excluding = true, bool $ignoreEmptyValues = true)
    {
        if ($property === 'status') return strtoupper($value);
        return $value;
    }

    protected function importCustomProperty(string $property, $value, bool $replace = true, bool $rawDataMode = false, bool $writableOnly = false)
    {
        if ($property === 'secret') return trim($value);
        return $value;
    }
}

Useful flag presets:

  • CustomProperty::ON_IMPORT_AND_EXPORT_IN_ALL_MODES
  • CustomProperty::ON_IMPORT | CustomProperty::ON_JSON_MODE
  • CustomProperty::ON_EXPORT | CustomProperty::ON_RAW_MODE

Property Types Reference

Common property types:

  • Property::IS_STRING
  • Property::IS_STRING_ENCRYPTED
  • Property::IS_INTEGER
  • Property::IS_FLOAT
  • Property::IS_BOOLEAN
  • Property::IS_DATE
  • Property::IS_ENUM
  • Property::IS_ENUM_NULLABLE
  • Property::IS_ARRAY
  • Property::IS_ARRAY_ENUM
  • Property::IS_OBJECT
  • Property::IS_OBJECT_NULLABLE
  • Property::IS_DICTIONARY
  • Property::IS_BINARY

Access types:

  • Property::READ_ONLY
  • Property::READ_WRITE
  • Property::WRITE_ONLY