cakephp: How to load Flash component in the plugin? - plugins

I am using CakePHP 3 and add a plugin cakphp-Notifier.
I want to add flash component in that plugin.
how to add cakephp default component in plugin?
Code:
NotificationManager.php
use Cake\Controller\Component\FlashComponent;
class {
// ...
private $Flash;
public function __construct( )
{
$this->Flash = new FlashComponent();
}
// ...
public function send {
$smsAPI->sendSms($numbers, $message, $sender);
$this->Flash->success(__('SMS sent .'));
// ...
}
I got this error:
Required parameter $registry missing.
Invocation parameters types are not compatible with declared.

First you must import the component on the top of your plugin file:
use Cake\Controller\Component\FlashComponent;
Then import the component inside your Class
var $components = array('Flash');
Then use your Flash functions
$this->Flash->set(__('Error!'));
Hope it works!

Related

Call a method from default package in katalon

I have created a default class file for handling the xpath under default package,
public class TestObjectHelper {
/*
* TestObjectHelper will help the user to handle dynamic xpath
*/
public static TestObject getTestObjectWithXpath(String xpath) {
return new TestObject().addProperty('xpath', ConditionType.EQUALS, xpath)
}
}
I want to use it another package, but it is not identifying the above method.
import statement
You need to call the function the following,
import TestObjectHelper
or suggest to move this under a separate package let's call it as com.utilites
import com.utilites.TestObjectHelper

Adding custom extjs module in TYPO3 backend

I'm currently trying to create a node resolver for a TCA column. I've added a resolver and an element. The render function in the element class looks like this
public function render()
{
$resultArray = $this->initializeResultArray();
$resultArray['requireJsModules'][] = 'MyVendor/MyExtension/MyModule';
$resultArray['html'] = 'Hallo Welt';
return $resultArray;
}
The extjs modules is placed in typo3conf/ext/my_extension/Resources/Public/JavaScript/MyModule.js
When TYPO3 renders my element, it renders the html part and tries to load the extjs module with the path typo3/MyVendor/MyExtension/MyModule.js
My question now is, how can I add my custom extjs module, that is injected by require function in JavaScript?
I'm using TYPO3 7.6.15.
I'm thankful for every help :)
Just found the answer here https://forum.typo3.org/index.php/t/210780/
The module needs to have TYPO3/CMS as vendor. Than it load loaded correctly.
public function render()
{
$resultArray = $this->initializeResultArray();
$resultArray['requireJsModules'][] = 'TYPO3/CMS/MyExtension/MyModule';
$resultArray['html'] = 'Hallo Welt';
return $resultArray;
}
The module needs to be in typo3conf/ext/my_extension/Resources/Public/JavaScript/MyModule.js

Symfony serializer - set circular reference global

Is there any way to set the circular reference limit in the serializer component of Symfony (not JMSSerializer) with any config or something like that?
I have a REST Application with FOSRestBundle and some Entities that contain other entities which should be serialized too. But I'm running into circular reference errors.
I know how to set it like this:
$encoder = new JsonEncoder();
$normalizer = new ObjectNormalizer();
$normalizer->setCircularReferenceHandler(function ($object) {
return $object->getName();
});
But this has to be done in more than one controller (overhead for me).
I want to set it globally in the config (.yml) e.g. like this:
framework:
serializer:
enabled: true
circular_limit: 5
Found no serializer API reference for this so I wonder is it possible or not?
For a week have I been reading Symfony source and trying some tricks to get it work (on my project and without installing a third party bundle: not for that functionality) and I finally got one. I used CompilerPass (https://symfony.com/doc/current/service_container/compiler_passes.html)... Which works in three steps:
1. Define build method in bundle
I choosed AppBundle because it is my first bundle to load in app/AppKernel.php.
src/AppBundle/AppBundle.php
<?php
namespace AppBundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AppBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new AppCompilerPass());
}
}
2. Write your custom CompilerPass
Symfony serializers are all under the serializer service. So I just fetched it and added to it a configurator option, in order to catch its instanciation.
src/AppBundle/AppCompilerPass.php
<?php
namespace AppBundle;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
class AppCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$container
->getDefinition('serializer')
->setConfigurator([
new Reference(AppConfigurer::class), 'configureNormalizer'
]);
}
}
3. Write your configurer...
Here, you create a class following what you wrote in the custom CompilerPass (I choosed AppConfigurer)... A class with an instance method named after what you choosed in the custom compiler pass (I choosed configureNormalizer).
This method will be called when the symfony internal serializer will be created.
The symfony serializer contains normalizers and decoders and such things as private/protected properties. That is why I used PHP's \Closure::bind method to scope the symfony serializer as $this into my lambda-like function (PHP Closure).
Then a loop through the nomalizers ($this->normalizers) help customize their behaviours. Actually, not all of those nomalizers need circular reference handlers (like DateTimeNormalizer): the reason of the condition there.
src/AppBundle/AppConfigurer.php
<?php
namespace AppBundle;
class AppConfigurer
{
public function configureNormalizer($normalizer)
{
\Closure::bind(function () use (&$normalizer)
{
foreach ($this->normalizers as $normalizer)
if (method_exists($normalizer, 'setCircularReferenceHandler'))
$normalizer->setCircularReferenceHandler(function ($object)
{
return $object->getId();
});
}, $normalizer, $normalizer)();
}
}
Conclusion
As said earlier, I did it for my project since I dind't wanted FOSRestBundle nor any third party bundle as I've seen over Internet as a solution: not for that part (may be for security). My controllers now stand as...
<?php
namespace StoreBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class ProductController extends Controller
{
/**
*
* #Route("/products")
*
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$data = $em->getRepository('StoreBundle:Product')->findAll();
return $this->json(['data' => $data]);
}
/**
*
* #Route("/product")
* #Method("POST")
*
*/
public function newAction()
{
throw new \Exception('Method not yet implemented');
}
/**
*
* #Route("/product/{id}")
*
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$data = $em->getRepository('StoreBundle:Product')->findById($id);
return $this->json(['data' => $data]);
}
/**
*
* #Route("/product/{id}/update")
* #Method("PUT")
*
*/
public function updateAction($id)
{
throw new \Exception('Method not yet implemented');
}
/**
*
* #Route("/product/{id}/delete")
* #Method("DELETE")
*
*/
public function deleteAction($id)
{
throw new \Exception('Method not yet implemented');
}
}
The only way I've found is to create your own object normalizer to add the circular reference handler.
A minimal working one can be:
<?php
namespace AppBundle\Serializer\Normalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
class AppObjectNormalizer extends ObjectNormalizer
{
public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, PropertyAccessorInterface $propertyAccessor = null, PropertyTypeExtractorInterface $propertyTypeExtractor = null)
{
parent::__construct($classMetadataFactory, $nameConverter, $propertyAccessor, $propertyTypeExtractor);
$this->setCircularReferenceHandler(function ($object) {
return $object->getName();
});
}
}
Then declare as a service with a slithly higher priority than the default one (which is -1000):
<service
id="app.serializer.normalizer.object"
class="AppBundle\Serializer\Normalizer\AppObjectNormalizer"
public="false"
parent="serializer.normalizer.object">
<tag name="serializer.normalizer" priority="-500" />
</service>
This normalizer will be used by default everywhere in your project.

Customize Editview in Custom Safe Manner

Is there a way to customize module(Eg:Contacts) in an custom safe manner.
My requirement is too load one javascript in editview of Contacts module.
I have currently called the js in custom/modules/Contacts/views/view.edit.php and have created an addon for same.
But when I will upload the addon , if that file custom/modules/Contacts/views/view.edit.php already present will be overridden.
Is there an other way to do the same which do not removes customizations?
You can do the following:
<?php
require_once("modules/Contacts/views/view.edit.php");
class CustomContactsViewEdit extends ContactsViewEdit
{
public function __construct(){
parent::__construct();
}
public function display(){
parent::display();
//Load your javascript file here
}
}
OR You can include your javascript file on the editviewdefs metadata.
$viewdefs['Contacts']['EditView]['templateMeta']['includes][] = array(
'file' => 'custom/modules/Contacts/CustomJs.js',
);
Havent checked this code but it will surely work.

Loading external library into ExpressionEngine plugin

I'm trying to load an external library into an ExpressionEngine plugin but am getting:
Message: Undefined property: Detector::$EE
In the plugin itself I've got:
public function __construct()
{
$this->EE->load->library('detector');
$this->EE =& get_instance();
}
and my folders are set up like:
detector
-libraries
--Detector.php
-pi.detector.php
What am I doing wrong?
Having moved past the loading library error, I'm now getting an 'undefined variable' error with the following code:
public function detector()
{
return $ua->ua;
}
public function user_agent()
{
return $ua->ua;
}
That's if I have {exp:detector:user_agent} in my template. If I {exp:detector} I get no output.
you should change your code like this:
$this->EE =& get_instance();
$this->EE->load->add_package_path(PATH_THIRD.'/detector');
$this->EE->load->library('detector');
First initialize the $this->EE variable, then you can load the library. So in this case it would be
$this->EE->detector->user_agent();