Symfony2: How to override a vendor file - php

I know how to override anypart of a bundle in Symfony2. I followed this
and it worked.
But what if I want to override a file in the vendor folder which is not part of a bundle.
In my specific example I need to override
vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php
Is this possible? Thanks for your help

You have to tell the EntityManager which Metadata Driver to use:
<?php
$driver = new \Doctrine\ORM\Mapping\Driver\XmlDriver('/path/to/mapping/files');
$em->getConfiguration()->setMetadataDriverImpl($driver);
Instead of the default XmlDriver, you use your extended version, e.g.
<?php
$driver = new \My\XmlDriver('/path/to/mapping/files');
$em->getConfiguration()->setMetadataDriverImpl($driver);
The $em in this snippet is the EntityManager.
See http://docs.doctrine-project.org/en/latest/reference/metadata-drivers.html for further details on how to write and use your own Metadriver implementations.

Related

Doctrine ORM not working with the Migrations

Good Day, my friends.
I want to use the doctrine ORM with the Migrations.
The issue is next: I want to place the migration configuration file in the specific folder. For example: 'config/doctrine-migrations.php'.
Everything working fine when I follow the official documentation and place the migrations.php file in the root folder, but when I try to place it in the specific folder system is not working.
My cli-config.php content is:
<?php
require_once "app/bootstrap.php";
return \Doctrine\ORM\Tools\Console\ConsoleRunner::createHelperSet($container->get(\Doctrine\ORM\EntityManager::class));
Well, I can change this file in a next way:
<?php
require_once "app/bootstrap.php";
return \Doctrine\Migrations\DependencyFactory::fromEntityManager(
new \Doctrine\Migrations\Configuration\Migration\PhpFile(BP . '/config/doctrine-migrations.php'),
new \Doctrine\Migrations\Configuration\EntityManager\ExistingEntityManager($container->get(\Doctrine\ORM\EntityManager::class))
);
After this, Doctrine Migration working fine, but Doctrine ORM stop working with the next error:
Argument #1 ($helperSet) must be of type Symfony\Component\Console\Helper\HelperSet, Doctrine\Migrations\DependencyFactory given
If someone knows how to solve my issue and use a specific config file please clarify a possible solution.
Best Regards, Mavis.
I may be a bit late, but i ran into the same problem as you.
You can use the same cli-config for migrations and orm. For that, you need add
the orm commands manually to the cli-config.php.
My cli config looks like this:
$em = getEntityManager();
$config = new PhpFile('migrations.php');
$dependencyFactory = DependencyFactory::fromEntityManager($config, new ExistingEntityManager($em));
$migrationCommands = [
new Command\DumpSchemaCommand($dependencyFactory),
new Command\ExecuteCommand($dependencyFactory),
new Command\GenerateCommand($dependencyFactory),
new Command\LatestCommand($dependencyFactory),
new Command\ListCommand($dependencyFactory),
new Command\MigrateCommand($dependencyFactory),
new Command\RollupCommand($dependencyFactory),
new Command\StatusCommand($dependencyFactory),
new Command\SyncMetadataCommand($dependencyFactory),
new Command\VersionCommand($dependencyFactory),
];
$customCommands = [];
$commands = array_merge($migrationCommands, $customCommands);
ConsoleRunner::run(new SingleManagerProvider($em), $commands);
All my import statements, are not included in this example, but you can
get them from the docrtine documentation
Looks like I found an answer.
I can add custom integration in my application by this guide: https://www.doctrine-project.org/projects/doctrine-migrations/en/3.0/reference/custom-integration.html
In a custom file, I can configure whatever I want.
Hope that this solution will help somebody else.

Using an extension's class from inside my controller (yii2 application)

I'm trying to use a method from inside my controller.
This works inside my "view"
use aweber\aweber\aweber_api;
$consumerKey = "XXXX";
$consumerSecret = "XXXXX";
$aweber = new AWeberAPI($consumerKey, $consumerSecret);
but it doesn't work in my controller.
I get the error
Class 'app\controllers\AWeberAPI' not found
Any hints?
I think you extracted AWeber-API-PHP-Library to the path aweber\aweber\aweber_api. The directory structure could be
$ ls aweber\aweber\aweber_api
aweber.php
aweber_api.php
....
If you autoloading classes with composer, AWeberAPI is in root namespace
use \AWeberAPI;
$aweber = new AWeberAPI($consumerKey, $consumerSecret);
If you are not autoloading with composer
require_once('aweber_api/aweber_api.php');
$aweber = new AWeberAPI($consumerKey, $consumerSecret);
Normally the extensione related are in vendor namespace ..
try with
use vendor\aweber\aweber_api;
You have a typo. The name of the php file usually is the same name of the class. So your code should be:
use aweber\aweber\AWeberAPI;
If it isn't, you can try:
use aweber\aweber\aweber_api as AWeberAPI;
Thanks for all the comments here. To fix it I actually moved this functionality into my "view" instead of having it in my controller and it worked.
I wasn't able to test the responses here, so if anyone else if facing the same issues, I'd recommend trying some of these answers.

Installing Uploader Plugin for CakePHP 2.x

So I'm new at this whole CakePHP thing, but I'm looking to get the Uploader plugin installed. I'm stuck at the first installation step, after download/placing the files in the correct place: http://milesj.me/code/cakephp/uploader. I see this is the code I need to add somewhere:
// CakePHP 2
CakePlugin::load('Uploader');
App::import('Vendor', 'Uploader.Uploader');
$this->Uploader = new Uploader();
But I don't know where to put it! I'm using the basic "Blog tutorial", but I changed the name from "Posts" to "Media". Where would I put this code to get the plugin included? I'm not sure on the rest of the steps either, so if anyone could help me with that in terms of the default "Blog tutorial" setup, that'd be awesome. Thanks!
EDIT: I have the CakePlugin part working. I'm just unsure about the App:import line. I keep trying to add it inside my MediaController class, but it's just throwing errors. Where would this line go?
EDIT: App:import line is working, now I just need the new Uploader() part
I havn't used this specific plugin, but I have used one similar (MeioUpload).
The CakePlugin::load('Uploader') goes in your bootstrap configuration file (app/config/bootstrap.php)
App::import and the creation are likely to be handled within your "Media" controller.
For example. My Cake App uses App::uses('Sanitize', 'Utility'); in its PostController.
EDIT:
I assume it would be something like this.
<?php
App::import('Vendor', 'Uploader.Uploader');
class MediaController extends AppController {
$this->Uploader = new Uploader();
/* The rest of the controller */
}
But I could be wrong. The explanation for that plugin is weird.

How to enable ORM annotation prefix outside of Symfony2?

I'm converting an old PHP project to the Symfony2 framework. Some of the pages are now handled by my Symfony2 front controller (index.php), but many pages have not yet been converted.
The problem is that, within Symfony, all of my Doctrine entity annotations must begin with the ORM\ prefix, but outside of Symfony, that prefix does not appear to be enabled, and so I get the following error:
Class MyProject\MyBundle\Entity\MyClass is not a valid entity or mapped super class.
I've tried to duplicate whatever magic Symfony does to set this up, including following these instructions [doctrine-project.org], and actually including app/autoload.php entirely into my legacy bootstrap process. But nothing works.
Does anyone know how I can manually replicate whatever it is that Symfony does to enable the ORM\ prefix for my Doctrine annotations?
I got the answer from the Symfony2 Google group. The problem is that the Doctrine configuration shown in the documentation uses SimpleAnnotationReader behind the scenes, but you need regular AnnotationReader to use the ORM\ namespace prefix. I got it to work by replacing this:
$config = new Doctrine\ORM\Configuration();
$driver = $config->newDefaultAnnotationDriver('/path/to/my/entities');
with this:
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
// ...
$config = new Doctrine\ORM\Configuration();
$reader = new AnnotationReader();
$driver = new AnnotationDriver($reader, '/path/to/my/entities');
I ended up with:
Doctrine\ORM\Tools\Setup::createAnnotationMetadataConfiguration($paths, $devMode, null, null, false);`
The 3rd and 4th null arguments are default. The 5th false argument tells it to make a standard AnnotationReader rather than a basic one.
I'm using Doctrine 2.5.6.
Explanation
I found I couldn't get Ian's solution working without calling Doctrine\ORM\Tools\Setup::createAnnotationMetadataConfiguration before making my own config. I was getting this error:
'[Semantical Error] The annotation "#Doctrine\ORM\Mapping\Entity" in class My\Class does not exist, or could not be auto-loaded.'
I was really confused so I took a look at the source code.
It turns out createAnnotationMetadataConfiguration calls Doctrine\ORM\Configuration::newDefaultAnnotationDriver rather than creating the annotation driver directly. This calls AnnotationRegistry::registerFile(__DIR__ . '/Mapping/Driver/DoctrineAnnotations.php'); which seems to be critical. After that, newDefaultAnnotationDriver just creates a new AnnotationDriver().

Developing/using a custom Resource Plugin in Zend Framework

We have used Zend_Log, which is configured in application.ini differently for different circumstances. We initialize it/get it in the bootstrap and store it in the registry:
$r = $this->getPluginResource('log');
$logger = $r->getLog();
But we've subclassed Zend_Log (say, Our_Log) to add customized features, and want to get it the same way. So then we have to make a new Resource Plugin. That seems quite easy - just copy Application/Resource/Log.php, rename the file to Ourlog.php, rename the class to class Zend_Application_Resource_Ourlog. For now, let's not worry about "Our_Log", the class -- just use the new Resource Plugin to get a Zend_Log, to reduce the variables.
So then, our new code in the bootstrap is:
$r = $this->getPluginResource('ourlog');
$logger = $r->getLog();
but of course this doesn't work, error applying method to non-object "r". According to the documentation,
"As long as you register the prefix path for this resource plugin, you
can then use it in your application."
but how do you register a prefix path? That would have been helpful. But that shouldn't matter, I used the same prefix path as the default, and I know the file is being read because I "require" it.
Anyway, any guidance on what simple step I'm missing would be greatly appreciated.
Thanks for the pointers -- so close, so close (I think). I thought I was getting it...
Okay, so I renamed the class Xyz_Resource_Xyzlog, I put it in library/Xyz/Resource/Xyzlog.php
Then, because I don't love ini files, in the bootstrap I put:
$loader=$this->getPluginLoader();
$loader->addPrefixPath('Xyz_Resource','Xyz/Resource/');
$r = $this->getPluginResource('xyzlog');
if (!is_object($r)) die ('Not an object!!');
Sudden Death. So, okay, do the ini:
pluginPaths.Xyz_Resource='Xyz/Resource/'
The same. No help. I believed that the basepaths of the plugin paths would include the PHP "include" paths. Am I mistaken in that? Any other ideas? I'll happily write up what finally works for me to help some other poor soul in this circumstance. Something to do with Name Spaces, maybe?
Plugin classes are resolved using the plugin loader, which works slightly differently to the autoloader; so just requiring the class in doesn't help you here. Instead, add this to your application.ini:
pluginPaths.Application_Resource = "Application/Resource"
you should then be able to use the class as normal. Since your path above will be checked before the default Zend one, you can also name your class 'Log' and still extend the Logger resource to override the standard functionality.

Categories