"Page not found" first plugin for OctoberCMS - php

I'm working on the backend side of a plugin and I'm having some issues getting it to work. I created all the plugin needed files, models, register things and so on but any time I try to access backend URL as per example http://alomicuba.dev/backend/alomicuba/balancerecharge I get a 404 error and I don't know what I''m doing wrong. This is the code on /plugins/alomicuba/balancerecharge/controllers/balancerecharge/BalanceRecharge.php file:
<?php namespace Alomicuba\BalanceRecharge\Controllers;
use Flash;
use BackendMenu;
use Backend\Classes\Controller;
use System\Classes\SettingsManager;
use Alomicuba\RechargeBalance\Models\Settings as BalanceRechargeSettings;
class BalanceRecharge extends Controller
{
public $implement = [
'Backend.Behaviors.FormController',
'Backend.Behaviors.ListController'
];
public $formConfig = 'config_form.yaml';
public $listConfig = 'config_list.yaml';
public $requiredPermissions = ['balancerecharge.*'];
public $bodyClass = 'compact-container';
public function __construct()
{
parent::__construct();
BackendMenu::setContext('Alomicuba.BalanceRecharge', 'balancerecharge');
SettingsManager::setContext('Alomicuba.BalanceRecharge', 'settings');
}
}
And this is the Plugin.php code:
class Plugin extends PluginBase {
/**
* Returns information about this plugin.
*
* #return array
*/
public function pluginDetails()
{
return [
'name' => 'Balance Recharge',
'description' => 'Plugin that allows users to recharge theirs balance through the PayPal payment gateway',
'author' => 'Dynamo Technology Solutions',
'icon' => 'icon-credit-card'
];
}
public function registerNavigation()
{
return [
'bradmin' => [
'label' => 'Balance Recharge',
'url' => Backend::url('alomicuba/balancerecharge/balancerecharge'),
'icon' => 'icon-credit-card',
'permissions' => ['brecharge.*'],
'order' => 500,
'sideMenu' => [
'brecharge' => [
'label' => 'Balance Recharge',
'icon' => 'icon-credit-card',
'url' => Backend::url('alomicuba/balancerecharge/balancerecharge'),
'permissions' => ['brecharge.*'],
],
]
]
];
}
public function registerSettings()
{
return [
'settings' => [
'label' => 'Balance Recharge PayPal Configuration',
'description' => 'Manage the settings for Balance Recharge.',
'category' => 'AloMiCuba',
'icon' => 'icon-cog',
'class' => 'Alomicuba\BalanceRecharge\Models\Settings',
'order' => 100
]
];
}
public function boot()
{
\App::register('Barryvdh\Omnipay\ServiceProvider');
\Illuminate\Foundation\AliasLoader::getInstance()->alias('Omnipay', 'Barryvdh\Omnipay\Facade');
UserModel::extend(function($model){
$model->hasMany['payment'] = ['Alomicuba\BalanceRecharge\Models\Payment'];
});
}
public function registerComponents()
{
return [
'Alomicuba\BalanceRecharge\Components\Payment' => 'Payment'
];
}
}
I'm missing something here?

In October CMS URL for controller is like
domain-name/backend/author-name/plugin-name/controller-name
so in your case you can use
alomicuba.dev/backend/alomicuba/balancerecharge/balancerecharge

Related

Laravel Error when referencing a resource in a resource

I'm using a Laravel Json Resource in my controller, as follows
public function index(Request $request)
{
$itemsWithTranslations = MenuItem::where(['menu_id' => $request->id, 'parent_id' => null])
->with(['children', 'translations'])
->orderBy('sort_order', 'asc')
->get();
return MenuItemResource::collection($itemsWithTranslations);
}
Now I would like to generate a collection, inside this collection with the children for the item that's being shown.
The following code works fine. Notice how I commented out the children reference
class MenuItemResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'text' => $this->title,
// 'children' => MenuItemResource::collection($this->whenLoaded('children')),
'data' => [
'id' => [
'value' => $this->id,
'type' => 'hidden'
],
'title' => [
'value' => $this->title,
'type' => 'text',
'label' => 'Title'
],
'resource_link' => [
'value' => $this->resource_link,
'type' => 'text',
'label' => 'Resource Link'
],
'translations' => MenuItemTranslationResource::collection($this->whenLoaded('translations'))->keyBy(function ($translation) {
return $translation['locale'];
})
]
];
}
}
When I uncomment the children, I get the following error
"Call to undefined method Illuminate\Http\Resources\Json\AnonymousResourceCollection::keyBy()"
Is it wrong, to include a Resource inside a resource? Or how should I go about this?
Model
class MenuItem extends Model
{
protected $table = 'menu_items';
protected $fillable = ['menu_id', 'parent_id', 'title', 'order', 'resource_link', 'html_class', 'is_blank'];
public function translations()
{
return $this->hasMany(MenuItemTranslation::class, 'menu_item_id');
}
public function children()
{
return $this->hasMany(MenuItem::class, 'parent_id');
}
}
Extra Information
When I return the following data, it does return empty as a collection for the children.
MenuItemResource::collection($this->children);
This returns
While if I return the children without a collection, it returns them (for 1 item, which is correct)
return $this->children;
returns
you should use ChildrenResource::collection
'children' => ChildrenResource::collection($this->whenLoaded('children'))
hope this works.
create a ChildrenResource class if not exists.

Prestashop - Integrate Bizum method

I am trying to integrate the BIZUM payment method in a prestashop store and for this I have installed the payment method addon "redsys" and I am modifying it, for what I have done is take the file redsys.php from the module and modify it by this code
/*
* HOOK V1.7
*/
public function hookPaymentOptions($params) {
if (! $this->active) {
return;
}
if (! $this->checkCurrency ( $params ['cart'] )) {
return;
}
$this->createParameter($params);
$urlBizum = 'https://sis-t.redsys.es:25443/sis/realizarPago';
$newOption2 = new \PrestaShop\PrestaShop\Core\Payment\PaymentOption();
$newOption2->setCallToActionText ($this->l('Pago con Bizum' ))
->setAction ($urlBizum)
->setInputs([
'Ds_SignatureVersion' => [
'name' =>'Ds_SignatureVersion',
'type' =>'hidden',
'value' =>$this->version2,
],
'Ds_MerchantParameters' => [
'name' =>'Ds_MerchantParameters',
'type' =>'hidden',
'value' =>$this->paramsBase64,
],
'Ds_Signature' => [
'name' =>'Ds_Signature',
'type' =>'hidden',
'value' => $this->signatureMac,
],
'Ds_Merchant_PayMethods' => [
'name' =>'Ds_Merchant_PayMethods',
'type' =>'hidden',
'value' => 'z',
],
]);
$payment_options = [$newOption2];
return $payment_options;
}
The problem I have is that I get the redsys TVP screen ... and not the bizum I'm waiting for.
Thank you

Extends User plugin by adding a profile does not render tab either new added fields in OctoberCMS

I've follow all the steps on the Extending User plugin screencast but for some reason I can not see "Profile" tab and either new added fields. Since I used the second approach, the easy one, this is what I've done:
Create the plugin and models and so on under Alomicuba namespace
Create and make the needed changes to the files as explained in video:
Plugin.php
<?php namespace Alomicuba\Profile;
use System\Classes\PluginBase;
use RainLab\User\Models\User as UserModel;
use RainLab\User\Controllers\Users as UsersController;
/**
* Profile Plugin Information File
*/
class Plugin extends PluginBase
{
public $requires = ['RainLab.User'];
/**
* Returns information about this plugin.
*
* #return array
*/
public function pluginDetails()
{
return [
'name' => 'Profile',
'description' => 'Add extra functionalities for Alomicuba WS by extends RainLab User',
'author' => 'DTS',
'icon' => 'icon-users'
];
}
public function boot()
{
UserModel::extend(function($model){
$model->hasOne['profile'] = ['Alomicuba\Profile\Models\Profile'];
});
UsersController::extendFormFields(function ($form, $model, $context){
if ($model instanceof UserModel)
return;
$form->addTabFields([
'pinCode' => [
'label' => 'PIN',
'tab' => 'Profile'
],
'phone2' => [
'label' => 'Teléfono (2)',
'tab' => 'Profile'
],
'phone3' => [
'label' => 'Teléfono (3)',
'tab' => 'Profile'
],
'phone4' => [
'label' => 'Teléfono (4)',
'tab' => 'Profile'
]
]);
});
}
}
add_profiles_fields_to_user_table.php
<?php namespace Alomicuba\Profile\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class AddProfilesFieldsToUserTable extends Migration
{
public function up()
{
Schema::table('users', function($table)
{
$table->integer('pinCode')->unsigned();
$table->dateTime('pinCodeDateTime');
$table->integer('phone2')->unsigned()->nullable();
$table->integer('phone3')->unsigned()->nullable();
$table->integer('phone4')->unsigned()->nullable();
});
}
public function down()
{
$table->dropDown([
'pinCode',
'pinCodeDateTime',
'phone2',
'phone3',
'phone4'
]);
}
}
version.yaml
1.0.1: First version of Profile
1.0.2:
- Created profiles table
- create_profiles_table.php
- add_profiles_fields_to_user_table.php
Profile.php (Model)
<?php namespace Alomicuba\Profile\Models;
use Model;
/**
* Profile Model
*/
class Profile extends Model
{
/**
* #var string The database table used by the model.
*/
public $table = 'alomicuba_profile_profiles';
/**
* #var array Relations
*/
public $belongsTo = [
'user' => ['RainLab\User\Models\User']
];
// This method is not need anymore since I'll use the second approach
public static function getFromUser($user)
{
if ($user->profile)
return $user->profile;
$profile = new static;
$profile->user = $user;
$profile->save();
$user->profile = $profile;
return $profile;
}
}
But when I edit a existent user I didn't see the 'Profile' tab and also didn't see any new added field. See image below:
Any advice around this? Did I miss something?
Also I have a few question around plugin extends:
How do I add a required field to the register form?
How do I display each new added field on the account form?
I haved tested your code on my machine you need to write
$require instead of $requires in plugin.php
please check documentation
http://octobercms.com/docs/plugin/registration#dependency-definitions
and when extendFormFields() method called for UserController you need to specify that you only want to extends fields for UserModel not for other
if (!$model instanceof UserModel)
return;
so plugin.php code look like this
<?php namespace Alomicuba\Profile;
use System\Classes\PluginBase;
use RainLab\User\Models\User as UserModel;
use RainLab\User\Controllers\Users as UsersController;
/**
* Profile Plugin Information File
*/
class Plugin extends PluginBase
{
public $require = ['RainLab.User'];
/**
* Returns information about this plugin.
*
* #return array
*/
public function pluginDetails()
{
return [
'name' => 'Profile',
'description' => 'Add extra functionalities for Alomicuba WS by extends RainLab User',
'author' => 'DTS',
'icon' => 'icon-users'
];
}
public function boot()
{
UserModel::extend(function($model){
$model->hasOne['profile'] = ['Alomicuba\Profile\Models\Profile'];
});
UsersController::extendFormFields(function ($form, $model, $context){
if (!$model instanceof UserModel)
return;
$form->addTabFields([
'pinCode' => [
'label' => 'PIN',
'tab' => 'Profile'
],
'phone2' => [
'label' => 'Teléfono (2)',
'tab' => 'Profile'
],
'phone3' => [
'label' => 'Teléfono (3)',
'tab' => 'Profile'
],
'phone4' => [
'label' => 'Teléfono (4)',
'tab' => 'Profile'
]
]);
});
}
}
and in add_profiles_fields_to_user_table.php
for dropping column write following code
Schema::table('users', function($table)
{
$table->dropDown([
'pinCode',
'pinCodeDateTime',
'phone2',
'phone3',
'phone4'
]);
}

How to pass options/params to formCollection fieldset in ZendFramework 2?

I have a Form which contains a formCollection with a select element that I want to populate with values (from SQL) depending on a POST param.
Passing this param from controller to form wasn't a problem but now I can't find a way to set/read that param in target_element of formCollection. Any ideas on how make that work?
Here's my code:
Controller
class MyController extends AbstractActionController{
public function indexAction()
{
$form = $this->serviceLocator->get('FormElementManager')->get('Module\Form\myForm');
$form->init([
'param' => $this->params()->fromPost('param')
]);
}
}
Form
class myForm extends Form
{
private $sm;
public function __construct($sm = null)
{
parent::__construct();
$this->sm = $sm;
}
public function init($params=[])
{
$this->add([
'name' => 'choices',
'type' => 'Zend\Form\Element\Collection',
'options' => [
'label' => 'SelectLabel',
'count' => 1,
'should_create_template' => true,
'allow_add' => true,
'template_placeholder' => '__placeholder__',
'target_element' => [
'type' => 'Module\Form\choicesFieldset',
'options' => [
'param' => isset($params['param']) ? $params['param'] : 0,
]
],
],
]);
}
}
Fieldset
class choicesFieldset extends Fieldset{
private $sm;
public function __construct($sm = null){
parent::__construct();
$this->sm = $sm;
}
public function init(){
$param = $this->getOption('param');
$availableChoices = /* SQL_QUERY_BASED_ON_PARAM; */
$this->add([
'name' => 'choice_1',
'type' => 'Select',
'options' => [
'label' => 'First choice',
'value_options' => $availableChoices,
]
]);
}
}
Thanks in advance for your help.
All you would need to do is fetch the Request instance from the service manager; check the parameter you want and then 'inject' it into the form.
It would make more sense to do so in the form factory; rather than repeat yourself within controllers.
For example:
public function getFormElementConfig()
{
return array(
'factories' => array(
'MyModule\Form\MyForm' => function($formElementManager) {
$serviceManager = $formElementManager->getServiceLocator();
$request = $serviceManager->get('Request');
// defaults to 0 if not set
$param = $request->getPost('the_posted_variable_name', 0);
$options = array(
'my_custom_option_name' => $param,
);
// You should maintain the Zend\Form\Element::__construct() method signuture
// as it allows for the 'options' to be passed in.
// Alternatively you could use $form->setOption('param', $options)
// and inject the options as a soft dependency
$form = new Form\MyForm('my_form', $options, $serviceManager);
// ... other form stuff here
return $form;
},
),
);
}
Now you can use the option within the form using:
$param = $this->getOption('my_custom_option_name');

ZF2 form element collection validation

So I have a "simple" form
class SiteAddForm extends Form
{
public function __construct()
{
parent::__construct('add_site_form');
$site = new SiteFieldSet();
$this->add($site);
}
public function getTemplate()
{
return 'site_add.phtml';
}
}
The form it self does nothing. It adds a field_set and returns a template name.
The SiteFieldSet looks likes:
class SiteFieldSet
extends FieldSet
implements InputFilterProviderInterface
{
public function __construct()
{
parent::__construct('site');
$name = new Text('name');
$this->add($name);
$domains = new Collection('domains');
$domains->setTargetElement(new DomainFieldSet())
->setShouldCreateTemplate(true);
$this->add($domains);
}
public function getTemplate()
{
return 'site.phtml';
}
/**
* Should return an array specification compatible with
* {#link Zend\InputFilter\Factory::createInputFilter()}.
*
* #return array
*/
public function getInputFilterSpecification()
{
return [
'name' => [
'required' => true,
'validators' => [
new StringLength([
'min' => 200,
])
]
],
'domains' => [
'required' => true,
],
];
}
}
It adds a text and collection element to the fieldset. The field set implements InputFilterProviderInterface to validate the data thrown into it.
The name must be at least 200 chars (for testing) and the collection is required.
But now comes my problem. With the field set that is thrown into the collection, code:
class DomainFieldSet
extends FieldSet
implements InputFilterProviderInterface
{
public function __construct()
{
parent::__construct('domain');
$host = new Url('host');
$this->add($host);
$language = new Select('language', [
'value_options' => [
'nl_NL' => 'NL',
],
]);
$this->add($language);
$theme = new Select('theme', [
'value_options' => [
'yeti' => 'Yeti',
]
]);
$this->add($theme);
}
public function getTemplate()
{
return 'domain.phtml';
}
/**
* Should return an array specification compatible with
* {#link Zend\InputFilter\Factory::createInputFilter()}.
*
* #return array
*/
public function getInputFilterSpecification()
{
return [
'host' => [
'required' => true,
'validators' => [
new StringLength([
'min' => 200,
])
]
],
'language' => [
'required' => true,
],
'theme' => [
'required' => true,
],
];
}
}
Again nothing special. There are now three elements defined host, theme & language. Again the field set implements InputFilterProviderInterface. So there must be an getInputFilterSpecification in the class.
When I fill in the form
site[name] = "test"
site[domains][0][host] = 'test'
site[domains][0][theme] = 'yeti'
site[domains][0][language] = 'nl_NL'
It gives an error for site[name] saying it must be atleast 200 chars, so validations "works"
But it should also give an error on site[domains][0][host] that it needs to be atleast 200 chars (code was copy pasted, and the use is correct).
So why doesn't the validation kicks in, and or how can I solve the issue so a element/field set inside a collection is properly validated
Try using setValidationGroup in the form __construct method
like:
public function __construct()
{
$this->add(array(
'type' => 'Your\Namespace\SiteFieldSet',
'options' => array(
'use_as_base_fieldset' => true,
),
));
$this->setValidationGroup(array(
'site' => array(
'domain' => array(
'host',
'language',
'theme',
),
),
));
}
or this may also work...
$this->setValidationGroup(FormInterface::VALIDATE_ALL);

Categories