I have configured Propel to work with Laravel with the help of http://picqer.com/blog/propel-with-laravel. All model queries are working fine and all data is being fetched properly.
However, the toJSON and exportTo('JSON') methods are not working neither on the Objects or nor on the PropelObjectCollection returned by certain queries.
The exceptions thrown by Laravel are:
For exportTo('JSON') and toJSON() all caps method
Unknown parser class "PropelArrayParser"
For toJson() method:
Unknown parser class "PropelJsonParser"
I think the problem lies somewhere with autoload of Laravel. I am perhaps missing an entry that'd help it locate PropelJsonParser file.
P.S. I have no idea what effects 'php artisan dump-autoload' causes. But I did run it as per tutorial.
The build.properties file looks like:
propel.project = QuranApp
propel.database = mysql
propel.mysql.tableType = InnoDB
propel.database.url = mysql:host=localhost;dbname=quransociety
propel.database.user = user
propel.database.password = password
propel.disableIdentifierQuoting = false
propel.php.dir = ${propel.project.dir}/../../models
propel.output.dir = ${propel.project.dir}/../../database/propel
propel.phpconf.dir = ${propel.project.dir}/conf
propel.schema.dir = ${propel.project.dir}
I've added those two lines in laravel start.php (at the beginning):
set_include_path(dirname(__DIR__) . '/vendor/propel/propel1/runtime/lib/parser' . PATH_SEPARATOR . get_include_path());
require dirname(__DIR__) . '/vendor/propel/propel1/runtime/lib/parser/PropelJSONParser.php';
so basically I'm including them by hand, and this error is gone. There should be other way, that plays nice along with larvel autoload mechanism, but so far I didn't solve it differently
Related
On my Laravel 8 application, I have a scenario where I generate the class name a call it. Here is the piece of code for it that I'm calling inside a trait:
$crm_class = "App\Lib\CRM\\" . Str::studly($lead->crm->name);
if (!class_exists($crm_class)) {
throw new \Exception('CRM CLass Not Found: ' . $crm_class);
}
return (new $crm_class)->generateLead($lead, $request);
Basically, depending on the name of the lead's CRM, I call a class that deals with that particular CRM. This could for example resolve to something like App\Lib\CRM\Acme
This works perfectly in my localhost setup, but when I run it on my AWS EC2 instance, the exception is thrown that "CRM CLass Not Found: \App\Lib\CRM\Acme".
I'm not using any use statements on the top for the CRM classes. I've also tried adding a \ before App with no success. I'm expecting to have about 5 different unique CRM classes.
Any idea why the code works on localhost and not elsewhere?
Turned out that Str::studly was producing a capital L in the class name, but my class name was using a lower case l. I changed the case, and the issue is resolved.
I wrote custom classes and want to use them in pimcore application.
I took them to /website/lib/Custom directory on server. Afterwards, I wrote recursive script includer for each Class located in the directory and included that script in /index.php file.
It is absolutely not pimcore standard but it works.
In pimcore/config/startup.php exists snippet:
$autoloaderClassMapFiles = [
PIMCORE_CONFIGURATION_DIRECTORY . "/autoload-classmap.php",
PIMCORE_CUSTOM_CONFIGURATION_DIRECTORY . "/autoload-classmap.php",
PIMCORE_PATH . "/config/autoload-classmap.php",
];
$test = PIMCORE_ASSET_DIRECTORY;
foreach ($autoloaderClassMapFiles as $autoloaderClassMapFile) {
if (file_exists($autoloaderClassMapFile)) {
$classMapAutoLoader = new \Pimcore\Loader\ClassMapAutoloader([$autoloaderClassMapFile]);
$classMapAutoLoader->register();
break;
}
}
I guess that this provides inclusion of all those classes put into returning array from autoload-classmap.php.
Having in mind that /pimcore/config/autoload-classmap.php exists, the mentioned loop would break at first iteration so classes that I would put into custom autoload-classmap are not going to be included in project.
My question is can I change files from /pimcore directory and expect that everything would be fine after system update?
No, you should not overwrite anything in the pimcore directory, since the files in there get overwritten by the update mechanism.
You can do what you want by using the /website/config/startup.php which will not get overwritten:
https://www.pimcore.org/wiki/display/PIMCORE4/Hook+into+the+startup-process
But instead of loading all your classes as you did, take advantage of the autoloader by adding this to the /website/config/startup.php:
// The first line is not absolutely necessary, since the $autoloader variable already gets
// set in the /pimcore/config/startup.php, but it is a more future-proof option
$autoloader = \Zend_Loader_Autoloader::getInstance();
$autoloader->registerNamespace('Custom');
If you are properly using namespaces and naming your files correctly that's all you need to do.
I want to run custom php code in laravel directly without using any routes or http requests..
I hope I can make it clear, I mean, like those online tools that runs php code by writing php code in browser, and then run it, and view result..
I found this handy project (Run-PHP-Code) to run PHP in browser directly, but I can't use models of my laravel project in PHP code..
How can I include laravel 's environment, so that I can for example:
$tag= new Tag;
where Tag is a model in laravel project, that would result into:
Fatal error: Class 'Tag' not found in D:\xampp\htdocs\widgetsRepository\app\controllers\Run-PHP-Code-master\index.php(49) : eval()'d code on line 3
Any idea? this would be very useful!
EDIT
I tried Brian suggestion at his answer, but I got this error now:
Call to a member function connection() on null
at vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php
public static function resolveConnection($connection = null)
{
return static::$resolver->connection($connection);
}
so, I think I only need to get database sorted, then I can do experiments easily..
I've never tried to run code from a laravel project directly, I just copy and paste parts of the code into Run PHP Code.
That being said, it should be possible to run the code using the method taken from this StackOverflow question:
The Composer autoload script, to autoload all of your classes:
require __DIR__.'/../bootstrap/autoload.php';
And if you need things from the IoC container, you'll:
$app = require_once __DIR__.'/../bootstrap/start.php';
Then you will be able to do things like:
$post = Post::find(1);
I once spent over an hour reverse engineering the xPDO constructor to figure out how to load base packages upon instantiation.
Unfortunately, I have lost that little snippet of code! And I'm left with this.
$this->database = new xPDO(
"mysql:host=" . $this->config->item('hostname', XPDO) .
";dbname=" . $this->config->item('database', XPDO),
$this->config->item('username', XPDO),
$this->config->item('password', XPDO),
$this->config->item('dbprefix', XPDO)
);
// This is line I would like to pass to the constructor.
$this->database->addPackage('packageName', $this->config->item('core_path') . "components/package/model/", '_packagePrefix');
I cannot find this anywhere in the documentation.
EDIT
With xPDO, you have to specifically add packages that are not loaded by default. And by default, xPDO doesn not load any packages on instantiation.
However, I did once spend a considerable amount of time, deconstructing the constructor of xPDO and found that there is an optional parameter that allows you to define an array of packages that will be loaded on instantiation.
My problem is that I cannot remember how to do this.
You can load base packages passing the right options to the xPDO constructor. This is the constructor definition:
$xpdo= new xPDO($dsn, $username= '', $password= '', $options= array(), $driverOptions= null)
The options array support many different configurations, the one you are looking for is xPDO::OPT_BASE_PACKAGES:
xPDO::OPT_BASE_PACKAGES — A comma-separated string of package
names/paths (separated by a colon) to be loaded upon instantiation.
Basically, you can do what you want modifying your code in this way:
$this->database = new xPDO(
"mysql:host=" . $this->config->item('hostname', XPDO) .
";dbname=" . $this->config->item('database', XPDO),
$this->config->item('username', XPDO),
$this->config->item('password', XPDO),
array(xPDO::OPT_BASE_PACKAGES => "package1:path1;prefix, package2:path2, ...")
);
Here's a link to the documentation where you can find further details about the options array: http://rtfm.modx.com/xpdo/2.x/getting-started/fundamentals/xpdo,-the-class/the-xpdo-constructor
EDIT
The format of the string is as follow:
"package_name:absolute_path;prefix"
prefix is optional. I have updated the code above with this format string.
While I'm not completely sure what you're asking for I suspect you are asking if there is some known method of passing an array of package names for packages with the same path.
Assuming this is correct I have the following possible solution (and if it's not then please, as scragar requested, clarify what you are asking):
Having looked # the file xpdo.class.php in the class xPDO & method addPackage() I see that it specifically verifies that the package name is a string & produces an error if it is not.
Therefore this method, addPackage() certainly does NOT allow an array to be passed to it.
However, I suspect you may be remembering that, if you use addPackage() on a package/extra directory that has multiple xPDO classes & mapping files & a schema... that ALL of the database tables represented will be able to be instantiated & utilized to perform CRUD operations on.
As an example I have two packages (from separate extras) that have the following paths core/components/[packageName]/ (where the thing in the brackets would be the actual name of the particular package).
In addition the model files are located in core/components/[packageName]/model/[packageName]/ as well as the subdirectory /mysql.
In BOTH cases when I add the package [packageName] all classes are available to be instantiated, since I have not included/required any of the files then addPackage() appears to be including them & therefore making them available for use as xPDO objects by using the modx method newQuery()
(so in code thats:
$modx->newQuery(nameOfxPDOClassToBeInstantiated);
)
(NOTE: all of the necessary classes for my two packages where generated from custom DB tables utilizing the very handy tool provided by Bob Ray here and explained by him in a straightforward tutorial here).
Hope that helps.
As an afterthought, here's the xPDO documentation on addPackage:
http://rtfm.modx.com/xpdo/2.x/class-reference/xpdo/xpdo.addpackage
And here's the documentation on utilizing the objects...
http://rtfm.modx.com/xpdo/2.x/getting-started/using-your-xpdo-model/retrieving-objects
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().