Dynamically calling a class only works on localhost - php

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.

Related

Service override doesn't work as expected

I create a service inside my module with the name of an existing core service (prestashop.adapter.data_provider.product). It successfully replaces it as seen in php ./bin/console debug:container output.
In yaml:
prestashop.adapter.data_provider.product:
class: PrestaShop\Module\MyModule\Adapter\Product\ProductDataProvider
The problem now is that I have 500 errors in some pages in BO. These errors are type errors like:
Type error: Argument 4 passed to
PrestaShopBundle\Model\Product\AdminModelAdapter::__construct() must
be an instance of
PrestaShop\PrestaShop\Adapter\Product\ProductDataProvider, instance of
PrestaShop\Module\MyModule\Adapter\Product\ProductDataProvider given,
called in....
I understand now that, whenever a constructor has an argument of type ProductDataProvider, the app tries to load my service but find a differentuse statement in the class (i.e in PrestaShopBundle\Model\Product\AdminModelAdapter)
These errors can be fixed by replacing the use statement in each file containing the problem, but as you may know, touching core files must be avoided.
Is there a way of overriding an existing service, but also make the override work all across the app "bypassing the use statements of the old service".

Testing Laravel Service Providers

I'm (we're) creating a package that acts as a core component for our future CMS and of course that package needs some unit tests.
When the package registeres, the first thing it does is set the back/frontend context like this:
class FoundationServiceProvider extends ServiceProvider
{
// ... stuff ...
public function register()
{
// Switch the context.
// Url's containing '/admin' will get the backend context
// all other urls will get the frontend context.
$this->app['build.context'] = request()->segment(1) === 'admin'
? Context::BACKEND
: Context::FRONTEND;
}
}
So when I visit the /admin url, the app('build.context') variable will be set to backend otherwise it will be set to `frontend.
To test this I've created the following test:
class ServiceProviderTest extends \TestCase
{
public function test_that_we_get_the_backend_context()
{
$this->visit('admin');
$this->assertEquals(Context::BACKEND, app('build.context'));
}
}
When I'm running the code in the browser (navigating to /admin) the context will get picked up and calling app('build.context') will return backend, but when running this test, I always get 'frontend'.
Is there something I did not notice or some incorrect code while using phpunit?
Thanks in advance
Well, this is a tricky situation. As I understand it, laravel initiates two instances of the framework when running tests - one that is running the tests and another that is being manipulated through instructions. You can see it in tests/TestCase.php file.
So in your case you are manipulating one instance, but checking the context of another (the one that did not visit /admin and is just running the tests). I don't know if there's a way to access the manipulated instance directly - there's nothing helpful in documentation on this issue.
One workaround would be to create a route just for testing purposes, something like /admin/test_context, which would output the current context, and the check it with
$this->visit('admin/test_context')->see(Context::BACKEND);
Not too elegant, but that should work. Otherwise, look around in laravel, maybe you will find some undocumented feature.

How laravel classes are included?

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);

PHP activerecord exception : Base table or view not found

I am trying out php active record, it's a great ORM, however I am at a standstill.
I have looked around google, blogs, phpactiverecord documentation as well as statckoverflow for days but have not been able to come across a suitable solution to this problem.
I am able to carry out the basic CRUD (insert,fetch, modify and delete) operations however as soon as i validate an object property using a static $validates_uniqueness_of filter, i get
Fatal error: Uncaught exception 'ActiveRecord\DatabaseException'
With message
exception 'PDOException' with message 'SQLSTATE[42S02]: Base table or
view not found: 1146 Table 'test_ar.models' doesn't exist' in
C:\wamp\www\test_AR\AR\lib\Connection.php on line 325
Here is the code i used in full.
<?php
$path_to_AR = "AR/";
include $path_to_AR . "activerecord.php";
ActiveRecord\Config::initialize(function($cfg) {
$cfg->set_model_directory('model');
$cfg->set_connections(
array(
'development' => 'mysql://root:asdf#localhost/test_ar',
'test' => 'mysql://username:password#localhost/test_database_name',
'production' => 'mysql://username:password#localhost/production_database_name'
)
);
});
/*
class user extends ActiveRecord\Model
{
static $validates_presence_of = array(array('username', 'message' => 'Please supply a username')); //this works just fine
static $validates_uniqueness_of = array(array('username'));//this line causes the PDO exception
}
*/
$user = new user();
user::create((array('username'=>'mike','password'=>'test','created'=>time())));
$user::create(array('username'=>'mike')); //cannot even reach this line because of the exeption
References i have tried/looked at
https://github.com/kla/php-activerecord/issues/274 (though i don't really understand what's going on there)
http://www.phpactiverecord.org/projects/main/wiki/Validations#validates_uniqueness_of
http:// blog.felho.hu/what-is-new-in-php-53-part-2-late-static-binding.html
as well as many others.
Platform and php version
I am using php 5.3.4 and using nightly build (May 8 2013) I have almost failed to get my head around this. Please advise on how to correct this.
This has been solved by the question author:
After discussing it with a few developers on github. It seems this is a bug.
The work around was to create a custom validator in the model
public function validate() {
if ($this->is_new_record() && static::exists(array('conditions' => array('username' => $this->username)))) {
$this->errors->add('username', 'This username is already taken');
}
}
I had this error crop up today in a custom application, not Drupal.
my error was the exact same one.
however the issue was that I created the application on a windows server, then moved it to a linux based server.
apparently during creation the windows based application ran just fine, but threw the error mentioned after move to Linux.
THE ISSUE WAS:
--a database table that was created with a capital litter such as statePages... when it was created it was renamed to statepages without the camel case letter.
once I went into the application and where the app connected and drew information from the database, I removed the mismatch capital letter, and the application found the database table just fine and work like expected.
hope this helps someone else.

Issues with Searchable Behavior and PHP 4.x.x

I am trying to use Searchable Behaviour hosted here: http://code.google.com/p/searchable-behaviour-for-cakephp/
To initialize the search_index table with existing data, I have used this: http://code.google.com/p/searchable-behaviour-for-cakephp/issues/detail?id=1&q=controller Reply No. 2 which creates the class SearchController.
The code was working fine on my local test server which runs PHP5.
However, the server has PHP 4 and when I tried the code on server it gives this error:
Fatal error: Cannot redeclare class searchcontroller in LONG_PATH/cake/app/models/behaviors/searchable.php on line 2
Does it really has to do something with the PHP version or have I done some logical mistake?
Not sure, but you could try my Searchable plugin instead
I just changed the name of the search Initialization controller and it worked. Looks like there is a Search Class created with Searchable behaviour.
Also, while using searchable plugin for CakePHP 4.x.x, if html_entity_decode and iconv are giving problems(as they did to me), use ut8_decode for decoding in place of html_en... and just comment out the iconv. The result may look ugly, but it works for most cases.

Categories