在symfony项目上对作曲家管理的第三方软件包上的源文件进行更改

时间:2014-04-07 22:44:24

标签: symfony doctrine-orm composer-php packages require

我正在使用symfony框架处理Web应用程序。 我的数据库设计预先存在并不是'经典' - 也就是说,'hstore'和'json'的字段类型正在使用中。

到目前为止,我遇到了两个问题:

  1. Doctrine不支持PgSQL上的hstore或json字段格式 - 我设法改变DBAL驱动程序和ORM的供应商/原则的来源来执行此操作。
  2. Doctrine也有一个据说在早期版本中解决的BUG(使用最新版本的symfony),该bug与pg时间戳转换回PHP时间戳有关,时间格式不包括微秒('u' )虽然Pg确实用HH返回它:mm:ss.uuuuuu(http://www.doctrine-project.org/jira/browse/DBAL-33
  3. 让我们假设我能够通过源代码更改来修复这些问题。

    这里的问题是由不同的问题和我想到的替代方案组成的,我猜他们中的任何一个都会有好的答案。

    • 如果文件由作曲家管理,我如何保持更新?
    • 如果我改变了源代码,如何将其部署到另一个环境?
    • 是否有其他解决方案/ hakcs可以在不更改第三方软件包的情况下解决上述问题?
    • 有没有办法在作曲家中部署自定义提交(不介意分析DoctorineBundle)?
    • 在安装供应商后,有没有一种好方法可以“修补”源代码? (可能以某种方式安装后的脚本)

    我希望(但是怀疑)我可以从composer.json中删除相应包的require并保留新的vendor / files和我的src /但这不是我正在寻找的解决方案。

    注意我是使用作曲家进行所有这种依赖和包导入/管理的新手。

2 个答案:

答案 0 :(得分:2)

首先,Doctrine非常具有可扩展性。肯定应该有一种方法可以使用捆绑代码扩展它,而无需修改vendor/中的任何内容。

Doctrine的文档指出已经支持json类型:http://doctrine-dbal.readthedocs.org/en/latest/reference/types.html#mapping-matrix。根据文档,hstore不是,但如果你能实现它,那就值得合并到Doctrine项目中。

日期时间问题也是已知的:http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/known-vendor-issues.html#postgresql

在Forking Composer提供的库上:您可以在Github上分叉Doctrine并在repositories中添加composer.json块,指向您的分叉:

{
...
"repositories": [
         {
             "type": "vcs",
             "url": "http://github.com/**your/fork**"
         } 
    ]
}

使用Composer更新Doctrine包(应该是php composer.phar update doctrine/orm,或者doctrine/dbaldoctrine/common或者doctrine/doctrine-bundle如果您要分发捆绑包),它应该是拉你的fork代码而不是原始的Doctrine代码。观看您所要求的库中"name"的{​​{1}}值。

以下是关于分叉的更详细的教程:http://mnapoli.fr/overriding-dependencies-with-composer/

答案 1 :(得分:0)

经过一些研究后,可以扩展关于symfony的Doctrine(DoctrineBundle)以了解自定义类型。

json DBAL类型实际上称为json_array而不是json(doono为什么),hstore和inet需要实现为新类型(可能不需要inet,也许可以将其别名为字符串)。

我们需要以下两个步骤才能使一切正常工作(如果你只做其中一个,那么映射导入失败,或者缓存:清除失败)。

  1. 将全新类型注册为Doctrine类型

    # config.yaml
    doctrine:
            types:
                hstore:  vendor\MyBundle\Types\Hstore
                inet:  vendor\MyBundle\Types\Inet
    
  2. 事实证明bootstrap code是bundle的boot()方法;我们现在需要告诉ORM将数据库链接到这些类,如下所示:

    class MyBundle extends Bundle
    {
        public function boot()
        {
    
            $em = $this->container->get('doctrine')->getEntityManager();
            $platform = $em->getConnection()->getDatabasePlatform();
    
            //for some reason, Doctrine DBAL calls a json type json_array, we rename it / alias it here.
            $platform->registerDoctrineTypeMapping('Json', 'json_array');
            $platform->registerDoctrineTypeMapping('Hstore', 'hstore');
            $platform->registerDoctrineTypeMapping('Inet', 'inet');
        }
    }
    
  3. 一些试验和错误的混合+这两个文档: http://symfony.com/doc/current/cookbook/doctrine/dbal.html#registering-custom-mapping-types http://doctrine-orm.readthedocs.org/en/latest/cookbook/custom-mapping-types.html

    我还没有测试所有这些的实现,但至少现在app / console上没有任何例外。一旦我确定我的实现是正确的,我将使用类型来源进行更新。