CakePHP 3 - call object from other helper - php

I'm actually working on a Helper for CakePHP3 that include BsHelper and then the BsFormHelper.
Actually everything looks good, no problem with Bootstrap formats.
I try now to create a ckEditor instance, but I meet some several problems.
If i try to call my ckEditor like this :
$this->BsForm->ckEditor('test')
I just have some problems because the function ckEditor is in my BsFormHelper, and load function is in BsHelper. So when i try to access private var to know if i had to load ckEditor i got that issue :
Error: Call to a member function load() on a non-object
File C:\wamp3\www\wac_lucien\BsHelpersCakePHP3\3.2\plugins\BsHelpers\src\View\Helper\BsFormHelper.php
So in fact I know where is the issue :
In BsFormHelper my fonction looks like :
public function ckEditor($fieldName, $options = array(), $ckEditorOptions = array()) {
$options['type'] = 'textarea';
$out = $this->input($fieldName, $options);
// If there is a point in the fieldName
if (strpos($fieldName, '.') !== false) {
$nameForReplace = Inflector::camelize(Inflector::slug($fieldName));
} else {
$nameForReplace = $this->_modelForm . Inflector::camelize($fieldName);
}
$this->Bs->load('ckeditor');
$this->Bs->loadJS('CKEDITOR.replace("' . $nameForReplace . '", ' . json_encode($ckEditorOptions) . ');', true);
return $out;
}
And in my BsHelper i got :
public function load($key) {
if (!$this->__extensions[$key]['loaded']) {
foreach ($this->__extensions[$key]['css'] as $css) {
$this->loadCSS($css);
}
foreach ($this->__extensions[$key]['js'] as $js) {
$this->loadJS($js);
}
$this->__extensions[$key]['loaded'] = true;
}
return $this->__extensions[$key]['loaded'];
}
Values are in declaration like this
public $__extensions = array(
'jasny' => array(
'css' => array(
'//cdnjs.cloudflare.com/ajax/libs/jasny-bootstrap/3.1.3/css/jasny-bootstrap.min.css'
),
'js' => array(
'//cdnjs.cloudflare.com/ajax/libs/jasny-bootstrap/3.1.3/js/jasny-bootstrap.min.js'
),
'loaded' => true
),
'ckeditor' => array(
'css' => array(),
'js' => array(
'//cdn.ckeditor.com/4.5.8/standard/ckeditor.js'
),
'loaded' => true
)
);
Can someone help me to find out ? It looks like load function called in BsFormHelper can't access privates vars from BsHelper ...

seems you are just trying to use a helper in another helper
The manual says
You may wish to use some functionality already existing in another
helper. To do so, you can specify helpers you wish to use with a
$helpers array, formatted just as you would in a controller:
So in your BsFormHelper just do
public $helpers = ['Bs'];
and you're done

Related

Laravel: How to get the action names from a controller and their params as a string?

I looking for a function where I give a ControllerName as a param and it returns the functions in that controller. For example:
.
.
.
class ExampleController extends Controller {
public static function firstExample($param1 = ' ', $param2 = 0){
.
.
.
}
public static function secondExample($param3){
.
.
.
}
}
And if I call: $actions = MyController::getActions('ExampleController');
It outputs this structure:
array(
0 => array(
'name' => 'firstExample'
'params' => array(
0 => '$param1',
1 => '$param2',
)
),
1 => array(
'name' => 'secondExample'
'params' => array(
0 => '$param3',
)
)
);
I know how to write functions and controllers. My question is: how to get the function names and their params (and maybe their types if it's possible, too) from a different controller?
So if I understood correctly you want to get the methods of any controller, and their respective parameters.
Step 1 : Getting the methods name
Using the PHP's get_class_methods you can retrieve all the methods of a specific class.
function getActions($controllerName){
$class_methods = get_class_methods(controllerName); //getting them
foreach ($class_methods as $method_name) { //looping them
getParams($controllerName,$method_name);
}
}
Step 2 : Getting the methods parameters
Using PHP's ReflectionMethod class:
function getParams($controllerName,$method_name){
$method = new ReflectionMethod($className, $methodName);
$params = $method->getParameters();
foreach ($params as $param) {
echo $param->getName(); //add to array here
}
}
Now for getting the type, not sure if $param->getType() works, but it's just a matter of trying, anyway this is just the basic stuff, now you can manipulate the function to fit your needs.
Note: Not sure if there's a better way that comes with Laravel, this is a vanilla PHP way of doing it.
Best Regards.

Drupal 8 custom block (module) create twig template file

I have a custom Module that creates a custom Block which has field elements.
This all works fine but I need to theme this block. I have checked the other posts on here and tried with no luck.
I have enabled twig debug and got theme suggestions. Still no luck.
Can anyone please point me in the right direction.
This is what I have so far:
my_module/my_module.module
// nothing related in here
my_module/src/Plugin/Block/myModuleBlock.php
<?php
namespace Drupal\my_module\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Provides a 'ModuleBlock' block.
*
* #Block(
* id = "module_block",
* admin_label = #Translation("My Module"),
* )
*/
class ModuleBlock extends BlockBase {
public function blockForm($form, FormStateInterface $form_state) {
$form['test'] = array(
'#type' => 'select',
'#title' => $this->t('test'),
'#description' => $this->t('test list'),
'#options' => array(
'Test' => $this->t('Test'),
),
'#default_value' => isset($this->configuration['test']) ? $this->configuration['test'] : 'Test',
'#size' => 0,
'#weight' => '10',
'#required' => TRUE,
);
return $form;
}
/**
* {#inheritdoc}
*/
public function blockSubmit($form, FormStateInterface $form_state) {
$this->configuration['test'] = $form_state->getValue('test');
}
/**
* {#inheritdoc}
*/
public function build() {
$build = [];
$build['module_block_test']['#markup'] = '<p>' . $this->configuration['test'] . '</p>';
return $build;
}
}
my_module/templates/block--my-module.html.twig // as suggested by twig debug
<h1>This is a test</h1>
<div id="test-widget">{{ content }}</div>
I should also note that in my my_theme.theme I have this but I don;t think its relevant:
// Add content type suggestions.
function my_theme_theme_suggestions_page_alter(array &$suggestions, array $variables) {
if ($node = \Drupal::request()->attributes->get('node')) {
array_splice($suggestions, 1, 0, 'page__node__' . $node->getType());
}
}
As for what I've tried is this:
public function build() {
return array(
'#theme' => 'block--my-module'
);
}
But still no go.
Any help here is very much appreciated.
UPDATE: So I just got it to work but I still need help. I moved the template block--my-module.html.twig to my theme directory and it worked.
How do I get it to work in my module directory?
UPDATE: So I just got it to work but I still need help. I moved the
template block--my-module.html.twig to my theme directory and it
worked.
How do I get it to work in my module directory?
You can create a directory called templates/ in your modules root.
Place your template here.
Now let Drupal know you store the template in your module.
in your_module.module add this function:
function YOUR_MODULE_theme($existing, $type, $theme, $path) {
return array(
'block__my_module' => array(
'render element' => 'elements',
'template' => 'block--my-module',
'base hook' => 'block'
)
);
}
This is not tested. It´s the way it worked for my custom block.
Don´t forget to clear the cache.
To be able to add the twig file in your module, you need to make sure the module defines the reference, not the theme.
You can still implement hook_theme() in the module's .module file as follows:
function mymodule_theme($existing, $type, $theme, $path) {
return [
'mymodule_block' => [
'variables' => [
// define defaults for any variables you want in the twig file
'attributes' => [
'class' => ['my-module-class'],
], //etc
],
],
];
}
Then in your block's build() implementation you can add a reference to the new theme function:
public function build() {
// Load the configuration from the form
$config = $this->getConfiguration();
$test_value = isset($config['test']) ? $config['test'] : '';
$build = [];
$build['#theme'] = 'mymodule_block';
// You would not do both of these things...
$build['#test_value'] = $test_value;
$build['module_block_test']['#markup'] = '<p>' . $test_value . '</p>';
return $build;
}
Finally be careful about where you place your twig file and what you name it. Create a templates directory in your module directory, and replace the _ in the theme function name with -: mymodule-block.html.twig

WordPress Fatal error: require(): Failed opening required

( ! ) Fatal error: require(): Failed opening required '' /mvc_controller.php on line 265
I get this above error despite trying so many suggestions in the forums, stackexchange etc.
I am developing a plugin in WordPress 4.0.1 using WP MVC, and it also encapsulates ORM concept that is in-built with WP MVC. I couldnt find a solution for this.
Below is the code:
(Public Controller)
/app/controllers/geozone_rules_controller.php
<?php
class GeozoneRulesController extends MvcPublicController {
var $after = array('set_geozonerules');
public function set_geozonerules() {
$this->load_model('GeozoneRule');
$geozonerules = $this->GeozoneRule->find();
$this->set('geozonerules', $geozonerules);
}
// Overwrite the default index() method to include the 'is_public' => true condition
public function index() {
$objects = $this->GeozoneRule->find(array(
'joins' => array('Geozone', 'Country', 'Zone'),
'includes' => array('Geozone', 'Country', 'Zone'),
'selects' => array('Geozone.id, Geozone.geozone_name',
array('Country.id, Country.country_name',
array('Zone.id', 'Zone.zone_name',
array('GeozoneRule.id', 'GeozoneRule.ordering')
)
)))
);
$this->set('objects', $objects);
// pagination
$this->params['page'] = empty($this->params['page']) ? 1 : $this->params['page'];
$this->params['conditions'] = array('is_public' => true);
$collection = $this->model->paginate($this->params);
$this->set('objects', $collection['objects']);
$this->set_pagination($collection);
echo 'Add New Geozone Rule';
}
// GeozoneRule selects only GeozoneRule names and ids by default; to select all fields from GeozoneRule,
// we'll overwrite the default show() method
public function show() {
$object = $this->model->find_by_id($this->params['id'], array(
'includes' => array(
'Geozone',
'Country',
'Zone',
'GeozoneRule' => array(
'selects' => 'GeozoneRule.*'
)
)
));
if (!empty($object)) {
$this->set('object', $object);
$this->render_view('show', array('layout' => 'public'));
}
}
}
?>
Model:
<?php
class GeozoneRule extends MvcModel {
var $table = '{prefix}w2store_geozonerules';
var $primary_key = 'id';
var $display_field = 'id';
var $default_order = 'sort_name';
var $includes = array('Geozone', 'Country', 'Zone');
var $has_and_belongs_to_many = array(
'GeozoneRule' => array(
'join_table' => array('{prefix}w2store_geozones',
'fields' => array('id', 'geozone_name')),
array('{prefix}w2store_countries',
'fields' => array('id', 'country_name')),
array('{prefix}w2store_zones',
'fields' => array('id', 'zone_name')),
'fields' => array('id', 'ordering')
)
);
public function after_find($object) {
if (isset($object->geozonerules)) {
$geozonerule_names = array();
foreach($object->geozonerules as $geozonerule) {
$geozonerule_names[] = $geozonerule->name;
}
}
// print_r ($object);
// exit;
}
public function after_save($object) {
$this->update_sort_name($object);
}
public function update_sort_name($object) {
$sort_name = $object->geozonerule_name;
$this->update($object->__id, array('sort_name' => $sort_name));
}
}
?>
and now the error i got:
Warning: require(): Filename cannot be empty in /mvc_controller.php
on line 265 Call Stack
Time Memory Function Location . . 11 0.0659 3870616
Any possible solutions will be of much help. Thanks a lot.
Issue solved. Simple error made a lot of fuss.
In views/admin/ folder, there is a folder for the model GeozoneRule in the name 'geozonerules' and it was renamed to 'geozone_rules'. Now it is ok.
Naming of folders and files needs careful attention.
Thanks folks.

What is AuthComponent::getModel() alternative in cakePHP2x?

I am using a Remember Me Component. Actually, migrating a CakePHP 1.3 app to CakePHP 2x. I am stuck with this LAST PIECE of code that is RememberMeComponent.
The script which I see here to SET the cookie is :
function make( ) {
$data = array(
$this->ident_field => $this->_create_token( ),
$this->token_field => $this->_create_token( ),
);
$this->Cookie->name = $this->cookie_name;
$this->Cookie->time = $this->period;
$this->Cookie->key = base64url_encode(implode('::', $data));
$this->Cookie->secure = true;
$this->Auth->getModel()->save(array($this->Auth->userModel => array_merge(array('id' => $this->Auth->user('id')), $data)), false);
}
and checks with :
function check( ) {
$cookie = $this->Cookie->read($this->cookie_name);
if (empty($cookie)) {
return false;
}
$data = explode('::', base64url_decode($cookie));
$user = $this->Auth->getModel( )->find('first', array(
'conditions' => array(
$this->Auth->userModel.'.ident' => $data[0],
),
));
if ( ! $user) {
return false;
}
function base64url_encode is defined in bootstrap - so, it is valid function.
Now there is line:
$this->Auth->getModel()->save(array($this->Auth->userModel => array_merge(array('id' => $this->Auth->user('id')), $data)), false);
That is giving me an error:
Error: Call to undefined method AuthComponent::getModel()
File: /var/www/FlintStones/Controller/Component/RememberMeComponent.php
I checked Auth Component documentation but, it did not have any option where I could find the model for auth.
Thanks in advance.
PS: We cannot directly move to Auto Login (as you might have that in mind) or if you can also refer to a quick-step-by-step, please share. I might even consider that but, so far it is just to get the Auth model.
I had the same issue in the same component.
How to get $settings data out of CakePHP 2.0 FormAuthenticate object
Summary:
Use $this->Auth->userModel to get the model. If the value is null, it will default to 'User'.

How to test file's upload function with logic placed in rename filter (Zend_Form_Element_File)?

First my code:
class ProfileController extends Zend_Controller_Action {
private function getUploadAvatarForm()
{
$form = new Zend_Form;
$form->setAttrib('enctype', 'multipart/form-data');
$form->setAction($this->view->baseUrl('/profile/upload-avatar'))
->setName('uploadAvatarForm')
->setMethod('POST');
$element = new Zend_Form_Element_File('avatar');
$element->setLabel('Upload an image:')
->addFilter('Rename',
array('target' => '/path/toimages/directory/' . $this->userId . '.png',
'overwrite' => true)
);
$element->addValidator('Count', false, 1);
$element->addValidator('Size', false, 102400);
$element->addValidator('Extension', false, 'png');
$form->addElement($element, 'avatar')
->addElement('submit', 'submit_upload', array('label' => 'upload'));
return $form;
}
public function uploadAvatarAction()
{
$form = $this->getUploadAvatarForm();
$this->view->form = $form;
if (!$this->getRequest()->isPost() || !$form->isValid($_POST)) {
return;
}
if (!$form->avatar->receive()) {
... error...
}
... ok ...
}
}
The question is: part of buissiness logic is placed into Rename filter. In my vision it worth it, but may be I'm wrong.
I'm trying to test it:
public function testUploadFile()
{
$this->_doLogin('user', 'password');
$this->getRequest()
->setMethod('POST'));
$this->mockFileUpload();
$this->dispatch('profile/upload-avatar');
var_dump($this->getResponse()->getBody());
}
private function mockFileUpload()
{
$_FILES = array(
'avatar' => array(
'name' => 'test.png',
'type' => 'image/png',
'tmp_name' => '/tmp/test.png',
'error' => 0,
'size' => 10127));
}
but got:
The file 'avatar' was illegal uploaded, possible attack
Could you please suggest me how to test this situation?
(With filesystem everything will be ok - I'm going to use vfsStream for that, so the problem is only to emulate post upload)
In your test class, set your form to use an extended class of Zend_File_Transfer_Adapter_Http and override the isValid() method. You will obviously need to change the scope of your form function to public in your ProfileController. This is to be used with PHPUnit. I am not sure how to integrate it with Zend_Test_PHPUnit_ControllerTestCase just yet, but I will need to figure it out at some point and will update.
$class = new ProfileController();
$form = $class->getUploadAvatarForm();
$form->getElement('avatar')->setTransferAdapter(new MockAdapter());
MockAdapter.php
class MockAdapter extends Zend_File_Transfer_Adapter_Http
{
public function isValid($files = null)
{
return true;
}
}
I had a similar problem.
After some code reading and experimenting I discovered that my problem was caused by calling the isValid function of my form twice (caused by a minor code glitch).
Not exactly sure how but the double isValid was causing my tmp file (the uploaded file) to be deleted before the second isValid function was run, this made line 183 of Zend_Validate_File_Upload think that it wasn't a proper file upload (because the second time it looked for it it was already deleted):
If you want to check if your temp file isn't there for some reason modify line 183 of Zend_Validate_File_Upload:
case 0:
var_dump(file_exists($content['tmp_name']));
if (!is_uploaded_file($content['tmp_name'])) {
$this->_throw($file, self::ATTACK);
}
break;
Perhaps your rename filter is moving or renaming the file?

Categories