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

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.

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.

Laravel organize helper functions

Please, don't talk to technical in the answers:-D I am not a hardcore programmer.
What is a good way to store certain functions in Laravel? I have functions that apply on a "post" only or "media" only, like getAttributeList or getComponents. I say "Post" and "Media" because both have their own controller, model and views. It feels wrong to put it in the model because that should be database stuff right? And traits are more for recurring functions all over the place, right? So, right now I have one big file called Helpers.php. And uh, it is getting large... should I simply separate it in PostHelpers.php, MediaHelpers.php etc? Or is there a more elegant way in Laravel to do it?
It is quite simple : Just check your composer.json file at root directory of ur app. and under autoload section add :
"autoload": {
"psr-4": {
"App\\": "app/"
},
"files": ["app/helper.php"],
"classmap": [
"database/seeds",
"database/factories"
]
"files": ["app/helper.php"], This is the line you need to add in ur composer file and provide the path to file .
In my case i have created a file helper.php in App directory where i keep all my functions .
after this run this command :
composer dump-autoload
Now u can access your functions anywhere.
In your composer json file check this snippet
"autoload": {
"files": [
"app/Helpers/global_helper.php"
],
As you see I have auto loaded 1 single file called global_helper.php in a folder called Helpers Now in this file I have a function called loadHelper(...$files)
What this function does is
if (!function_exists('loadHelper')) {
function loadHelper(...$file_names)
{
foreach ($file_names as $file) {
include_once __DIR__ . '/' . $file . '_helper.php';
}
}
}
You can pass your file name as array or string and it will include those files into your Controller constructor
So In my Controller whenever I want some helper function I create a saperate helper file for that controller then in constructor i ust include it.
I am not sure if there is any better solution but so far this is how I am making all my projects .
I hope this will help you ;)

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"
]
},

Use another symfony2 project as vendor

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 !

Where can I put laravel 4 filter classes?

In laravel 4, you can create filter classes instead of putting the entire filter inside a closure -- great. But do these filters have to be entirely in the app/filters.php or app/routes.php?
Generally I like to do one file per class, but I imagine there's something better to do then a bunch of includes in the filters.php file. Where would you put these for laravel to find them automatically? For example:
Route::filter('Thing', 'ThingFilter');
# can I put this in its own file and have laravel automatically use it?
class ThingFilter {
function filter() { ... }
}
I've all my filters in a separate directory called filters.
And here's how my filters.php file look like...
//---------------------------------------------------------
// Route Filters
//---------------------------------------------------------
Route::filter('auth', 'AuthFilter#default');
Route::filter('auth.basic', 'AuthFilter#basic');
Route::filter('guest', 'AuthFilter#guest');
Route::filter('csrf', 'CsrfFilter');
I autoload them via composer.json
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/filters",
"app/presenters",
"app/repositories",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
]
},
After you update your composer.json file, you need to run the command
composer dump-autoload
To verfiy that you files will be loaded, check out
vendor/composer/autoload_classmap.php
There isn't a default to my knowledge, but you can call ClassLoader::addDirectories(array(app_path().'/filters')); to register your filter directory. The correct place to put that is in app/start/global.php where you should see some folders already being registered.
There is a 'local.php' which seems a candidate, but this is only meant for specific environments (usually development, provided you add a proper array or closure in $app->detectEnvironment()).

Categories