Use another symfony2 project as vendor - php

I have three projects X, Y and Z.
Project X does some admin functions for Y poject. The Entities for project Y are writen in the AppBudnle vendor. Now, I would like to also do some admin tasks for the project Z in X, but project Z has all entities in the src/Company/Z/Entity/...
I included the project Z as vendor in the project X with this autoload:
"autoload": {
"psr-0": {
"Company\\Z\\": ""
}
},
But when adding this to the AppKernel in the project X, it complains that
PHP Fatal error: Class 'Company\ZBundle\ZBundle' not found in ....
Am I missing something in the autoload?
The project Z entities dir is seen like this in the X project:
/vendor/company/z-bundle/company/ZBundle/src/company/ZBundle/Entity

I create an answer because comment section is too short :
In your composer.json try something like this, according to your own project :
"repositories": [
{
"type": "vcs",
"url": "git#github.com:You/companyZBundle.git"
},
],
"require": {
"php": ">=5.3.9",
...
"You/companyZBundle": "dev-master#dev"
}
In your AppKernel :
new Company\ZBundle\ZBundle()
And, as Cerad said, be careful about case !

Related

Creating and accessing custom module's REST routes in Prestashop 1.7.5

I am trying to create a custom controller in my Prestashop 1.7.5 module.
I created a custom controller:
# /var/www/html/modules/Profit/src/controller/ProductProfitController.php
namespace Profit\Controller;
use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController;
use Symfony\Component\HttpFoundation\JsonResponse;
class ProductProfitController extends FrameworkBundleAdminController {
public function test() {
return JsonResponse();
}
}
I loaded the class with my composer.json file:
# /var/www/html/modules/Profit/composer.json
{
"name": "company/profit",
"description": "Moduł opłacalności",
"authors": [
{
"name": "Name",
"email": "Email"
}
],
"require": {
"php": ">=5.6.0"
},
"autoload": {
"psr-4": {
"Profit\\Controller\\": "src/controller/"
},
"classmap": [
"Profit.php",
"src/"
],
"exclude-from-classmap": []
},
"config": {
"preferred-install": "dist",
"prepend-autoloader": false
},
"type": "prestashop-module",
"author": "Name",
"license": ""
}
I added a route in my module's routes folder
# /var/www/html/modules/Profit/config/routes.yml
update_price_cut:
path: Profit/price-cut
methods: [GET]
defaults:
_controller: 'Profit\Controller\ProductProfitController::test'
Yet I do not know how to access that route. I tried:
localhost:8001/admin-dev/Profit/price-cut
localhost:8001/modules/Profit/price-cut
localhost:8001/modules/Profit/Profit/price-cut
localhost:8001/Profit/price-cut
None of these work. Every single one of them leads to a 404 error.
Is this the proper way of creating routes to your module's custom controller? How can I fix this?
NOTE: This controller is supposed to be a BackOffice controller. I want to use it to update products' details from the default PrestaShop product list.
Try $this->generateUrl('update_price_cut') within admin controllers. It will generate a correct route to your controller. Or if you need it in a different place you can create own service and use it. More information you can find here
The existing answer didn't help me much, plus it doesn't mention the actual URL, for people stumbling on here through Google.
Setup
# /config/routes.yml
my_route_name:
path: /my_project/my_path # Leading / can be omitted
methods: [GET]
defaults:
_controller: 'Me\MyProject\Admin\Controllers\MyController::indexAction' # This can point to any class and any public method.
// my_project/admin/controllers/MyController.php
class MyController extends FrameworkBundleAdminController
{
public function indexAction(): string
{
return 'hello';
}
}
So then I went down the same path of trying to figure out the URL and I finally ended up here.
The actual controller URL
The method generateUrl, mentioned in the other answer is not present in any of my admin controllers for some reason. I looked and discovered it's defined in a Symfony trait. It essentially does this:
$this->container->get('router')->generate('my_route_name', [], UrlGeneratorInterface::ABSOLUTE_PATH);
Which finally returned the working URL:
/admin1/index.php/modules/my_project/my_path?_token=...
Hope this can help anyone else.

How can I create a custom voyager Form Field from package?

I'm trying to create a repository composer package to create a custom form field for Voyager, and I found this example: https://github.com/bnku/extended-bread-form-fields , but this it doesn't work for me.
So, how do I build a custom field form for Voyager? The result would be this:
I tried this repository example.
https://github.com/bnku/extended-bread-form-fields (It didn't work for me)
and this is my repository test:
https://github.com/manuel90/crop-image-field
This is my composer.json of my package:
{
"name": "manuel90/crop-image-field",
"description": "New voyager form field to cut image when uploading",
"authors": [
{
"name": "Manuel",
"email": "testmlzra#gmail.com"
}
],
"require": {
"tcg/voyager": "^1.1"
},
"autoload": {
"psr-4": {
"Manuel90\\CropImageField\\": "src/"
}
},
"extra": {
"laravel": {
"providers": [
"Manuel90\\CropImageField\\CropImageFieldServiceProvider"
]
}
}
}
I can see these lines there's a trouble, it didn't detect the class "Voyager", but I don't know how to fix it:
if( class_exists('Voyager') ) {
Voyager::addFormField(CropImageFormField::class);
}
https://github.com/manuel90/crop-image-field/blob/master/src/CropImageFieldServiceProvider.php#L34-L36
( According docs this is the way to add a custom form Docs here )
I expect to see in the BREAD edit section the new custom field listed on the input type option, like this:
You need to move the Voyager::addFormField call to the boot() method as this counts as a "piece of functionality" which should be called after the voyager service providers are properly registered.
This is missing from Voyager's documentation because they only document the use case for adding FormFields at app level where the call from the register method runs after all vendor Service Providers are registered.

How can I write an accessible class in the whole of project?

I use Laravel framework and this is my current directory:
As you see, there is a class named Log (the one I've selected). Now I need to make it global. I mean I want to make it accessible in everywhere and be able to I make a object (instance) of it in following files:
All files of classe folder
All controller
web.php file of
All file of views
Anyway I want to be able to make a instande of it and call its methods everywhere like this:
$obj = new Log();
$obj->insert($message);
How can I do that?
You can create global Laravel helper:
if (! function_exists('log')) {
function log($message)
{
(new Log)->insert($message);
}
}
Put it in helpers.php and add this to composer.json to load the helpers file:
"autoload": {
....
"files": [
"app/someFolder/helpers.php"
]
},
Then you'll be able to use this helper globally:
log('User added');
In views:
{{ log('User added') }}
Update
#stack, you're using wrong syntax for JSON (screenshot in comments), here's correct one:
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/"
},
"files": [
"app/Helpers/helpers.php"
]
},

Bronto's php lib and Composer not to loading classes

I am trying to get the Bronto api PHP lib to work with composers autoload. But no go. What is missing?
Composer.json:
{
"require": {
"slim/slim": "2.4.*",
"bronto/bronto-api-php-client": "dev-master"
},
"minimum-stability": "dev"
}
index.php
<?php
require '../vendor/autoload.php';
$app = new \Slim\Slim();
$app->get('/', function () {
$bronto = new \Bronto_Api();
$bronto->setToken($token); // Or pass $token to the constructor of Bronto_Api
$bronto->login(); // Only needs to be called once
});
$app->run();
Slim's framework loads fine. I just keep getting a 'Fatal error: Class 'Bronto_Api' not found in /app/location/'.
Any ideas on what could be going on?
This is 3 years after the original question was asked but I had the same problem trying to add the package to a Laravel project I was working on. I resolved it by adding the following to my composer.json (the one belonging to my project).
"autoload": {
"psr-0": {
"Bronto_": "./vendor/bronto/bronto-api-php-client/Symfony/Component/Console/src/"
}
}
It feels a little dirty but works OK.

Laravel 4: load class dynamically from string in database

I wish i knew how to search for this question / phrase it more appropriately. This hampered my search for prior questions; bear with me if this is a duplicate.
See the update / edits at the bottom of this post
Background / what i'm trying to do:
I have a URL that looks a lot like this:
http://myapp.com/calculate/$fileID/$calculateID
$fileID and $calculateID are keys that I use to keep track of a data set and something I call a 'calculation'. Essentially, that URL says perform $calculateID on the data in $fileID.
I go to my database (mongo) and ask for a php class name or sring or file path or what have you that matches $calculateID. For example's sake let's say the table looks like this:
+-----+-------------------+
| _id | phpFile |
+-----+-------------------+
| 1 | basicCalcs.php |
| 2 | advancedCalcs.php |
| 3 | summaryCalcs.php |
+-----+-------------------+
Note: is is safe to assume that each file in the phpFile column has a common interface / set of public methods.
Example:
http://myapp.com/calculate/23/2
would go to the database, get the data from set 23 and then load up the functions in advancedCalcs.php. Once advancedCalcs.php has been loaded, a function within will receive the data. From there, a set of calculations and transformations are performed on the data.
My question
My question is what is a 'laravel 4 friendly' way to dynamically load up advancedCalcs.php and feed the data into a set of methods? Is there a way to lazy load this type of thing. Currently, i am only aware of the very unsophisticated require_once() method. I would really like to avoid this as i am convinced that laravel 4 has functionality to dynamically load an underlying class and hook it up to a common interface.
EDIT 1
Thanks to Antonio Carlos Ribeiro, i was able to make some progress.
After running dump-autoload command, my vendor/composer/autoload_classmap.php file has a few new entries that look like this:
'AnalyzeController' => $baseDir . '/app/controllers/AnalyzeController.php',
'AppName\\Calc\\CalcInterface' => $baseDir . '/app/calculators/CalcInterface.php',
'AppName\\Calc\\basicCalcs' => $baseDir . '/app/calculators/basicCalcs.php',
With code like the sample below, i can create an instance of the basicCalcs class:
$className = "AppName\\Calc\\basicCalcs";
$instance = new $className;
var_dump($instance);
Where the basicCalcs.php file looks like this:
//PATH: /app/calculators/basicCalcs.php
<?php namespace Reporter\Calc;
class basicCalcs {
public function sayHi(){
echo("hello world! i am basicCalcs");
}
};
?>
Updated question:
How can i create an alias similar to the AnalyzeController entry in autoload_classmap.php rather than having to refer to basicCalcs.php with a full namespace?
Add your library folder to your composer.json autoload:
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/extended",
"app/calculators", <------- This is where you put all your calculators
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
]
},
Update your autoloaded classes:
composer dump-autoload
If you want to be sure it did worked, check if your classes are autoloaded opening the file
vendor/composer/autoload_classmap.php
To instantiate them dinamically you better have this as a table class names:
+-----+-------------------+-------------------+
| _id | phpFile | namespace |
+-----+-------------------+-------------------+
| 1 | basicCalcs | Reporter\Calc\ |
| 2 | advancedCalcs | Reporter\Calc\ |
| 3 | summaryCalcs | Reporter\Calc\ |
+-----+-------------------+-------------------+
Then you just have to use it
class CalculateController extends Controller {
public function calculate($fileID, $calculateID)
{
$file = phpFile::find($fileID);
$className = $file->namespace . $file->phpFile;
$calculator = new $className; //// <--- this thing will be autoloaded
return $calculator->calculate( $calculateID );
}
}
I'm assuming your calculators are all:
class basicCalcs {
public function calculate($calculateID)
{
return performCalculation( $calculateID ); /// something like this
}
}
And your router is somethink like
Route::get('/calculate/{fileID}/{calculateID}', array('as'=>'calculate', 'uses'=>'CalculateController#calculate'));
In Laravel4 the file composer.json is responsible for this, following is an example
{
"require": {
"laravel/framework": "4.0.*"
},
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
]
},
"scripts": {
"post-update-cmd": "php artisan optimize"
},
"config": {
"preferred-install": "dist"
},
"minimum-stability": "dev"
}
Notice the autoload section where classmap is used to to tell laravel4 from which folders it should load classes and also which file should it load. For example, "app/controllers", will be used to load all classes from the app/controllers folder and "app/tests/TestCase.php" will make Laravel4 to autoload the class TestCase.php from app/tests/ folder. So, add your library folder in to the classmap section. Once you have added your folder path in autoload -> classmap section then you have to run
composer dumpautoload // or
composer dump-autoload
from the command line.

Categories