phpMv / ubiquity

Ubiquity framework
https://ubiquity.kobject.net
Apache License 2.0
690 stars 60 forks source link

[cli] Custom transformers are not loaded when building cache files #71

Closed dasper closed 4 years ago

dasper commented 5 years ago

Documentation states to load transformers in app/config/services.php yet services.php are not used with the command to to generate cache files.

It appears to be an oversight in the command line tools to include other bootstrapping files or the documentation is incomplete on how to include custom transformers within the command line tool.

I am confused on how to address or fix this issue.

Steps

Expected Result

cache updated successfully

Actual Result

· Message : customTransformer value is not a declared transformer.
· File : ~/vendor/phpmv/ubiquity-dev/src/Ubiquity/orm/parser/ModelParser.php
· Line :  115

Versions

jcheron commented 5 years ago

In the file services.php, it is only necessary to add the startup of the TransformerManager for production:

\Ubiquity\contents\transformation\TransformersManager::startProd();

To register a custom Transformer and generate its cache, you should not do so in services (otherwise the cache is regenerated with each request and it no longer has any interest).

It is true that there is no command in the devtools that would allow this to be done (we will fix this).

In the meantime, you can do it in an action accessible in the dev part of a controller:

public function registerTransf(){
    TransformersManager::registerClassAndSave('custom', \transformers\customTransformer::class);
}

You can then apply it to a property of a model:

    /**
     * @column("name"=>"foo")
     * @transformer("custom")
    **/
    private $foo;

And generate the cache with the devtools:

Ubiquity init-cache

I don't have any errors when I do that...

jcheron commented 5 years ago

@dasper Is your problem solved?

Version 2.3.1 of Ubiquity and devtools 1.2.9 will introduce the possibility to configure the application according to the environment from an app/config/bootstrap.php file to be completed.

<?php
use Ubiquity\devtools\cmd\ConsoleFormatter as Console;

//Comments
//For development mode initialization
function _dev($devtools,$config){
    echo Console::showInfo("Development mode");
    $devtools->composer('update'));
}

//For Production mode initialization
function _prod($devtools,$config){
    echo Console::showInfo("Production mode");
    $devtools->composer('optimize'));
}

//Executed before all modes
function bs_before($devtools,$config){

}

//Executed after all modes
function bs_after($devtools,$config){
    //Initialize all caches
    $devtools->run('init-cache');
}

The creation of the Transformer cache is one possible use.

//Executed before all modes
function bs_before($devtools,$config){
    TransformersManager::registerClassAndSave('custom',\transformers\CustomTransformer::class);
}

The launch is done from the devtools, before starting the application:

Ubiquity bootstrap prod
dasper commented 5 years ago

Thank you for the quick response. I have been too busy to work on the proof of concept I have utilizing Ubiquity so I have not implemented these suggestions yet. I just wanted to make sure the issue I was experiencing was noted and that I could contribute with the little extra time I have.

For further information into the situation I am facing. We have a database that uses binary(16) values for the primary key to store a UUID and I am attempting to use new models for this legacy system. One criteria is to abstract the primary key to always be a hex representation in code.

jcheron commented 5 years ago

With Ubiquity, you could create a Transformer like this to do the job:

namespace transf;

use Ubiquity\contents\transformation\TransformerInterface;

/**
 * @see https://stackoverflow.com/questions/2839037/php-mysql-storing-and-retrieving-uuids
 */
class BinaryUUIDTransformer implements TransformerInterface{

    /**
     * Convert Binary To String UUID
     * @param string $value
     * @return string
     */
    public static function transform($value) {
        $string = \unpack("H*", $value);

        $uuidArray = \preg_replace(
            "/([0-9a-f]{8})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{12})/",
            "$1-$2-$3-$4-$5",
            $string
            );

        return \array_pop($uuidArray);
    }

    /**
     * Convert String UUID To Binary
     * @param string $value
     * @return string
     */
    public static function reverse($value) {
        return \pack("H*", \str_replace('-', '', $value));
    }
}
dasper commented 4 years ago

Thank you for your help! I am looking forward to more POCs I can implement using Ubiquity.

For the record, this was how I set up the transformer

<?php
namespace transformers;
use Ramsey\Uuid\Uuid;
use Ubiquity\contents\transformation\TransformerFormInterface;
use Ubiquity\contents\transformation\TransformerInterface;
use Ubiquity\contents\transformation\TransformerViewInterface;
class BinaryKey implements TransformerInterface, TransformerViewInterface, TransformerFormInterface
{
    public static function transform($value)
    {
        if (!empty($value)) {
            $value = bin2hex($value);
        }
        return $value;
    }
    public static function reverse($value)
    {
        if (!empty($value) && ctype_xdigit($value) && $value % 2 === 0) {
            $value = hex2bin($value);
        } else {
            $uuid = Uuid::uuid1();
            $a = explode('-', $uuid);
            //sorted for db optimizations
            $value = $a[2] . $a[1] . $a[0] . $a[3] . $a[4];
        }
        return $value;
    }
    public static function toView($value)
    {
        return self::transform($value);
    }
    public static function toForm($value)
    {
        return self::transform($value);
    }
}