How do I load a component inside a class that extends BaseAuthenticate in CakePHP? - authentication

I have created my own authenticator which handles OAuth 2:
class OauthAuthenticate extends BaseAuthenticate
I would like to use a custom component (extended from Component) in my OauthAuthenticate class.
How can I to load my component there? The traditional
public $components = array('OauthAuthenticate');
doesn't work - the component is not loaded.

BaseAuthenticate class cannot load component via $components array as is usual in controllers, but loading a component is possible in constructor:
private $utilComponent = null;
public function __construct(ComponentCollection $collection, array $settings)
{
$this->utilComponent = $collection->load('Util');
}

Related

Bytebuddy loaded class not found

I am trying to build a class that holds a reference to another class object through a field. Something like this:
Class A extends Parent {private B b;}
Class B extends Child {private String s;}
I am able to make and load Class B first, instantiate its object and set it to the field in class A by intercepting A's constructor.
However, when I try to load the unloaded type A it throws class not found exception for type B even though its already loaded.
I hope this is possible to do with bytebuddy. If yes, what am I doing wrong?
Here is the implementation:
private static final ClassLoader SYSTEM_CLASS_LOADER = ClassLoader.getSystemClassLoader();
public Class<? extends Parent> generateParentClass(ParentConfig config) throws Exception {
Map<String, Class<? extends Child>> fieldMap = config.getChildren().stream().collect(Collectors.toMap(ChildConfig::getName, this::generateChildClass));
Implementation.Composable constructorInterceptor = MethodCall.invoke(Parent.class.getConstructor());
for(Map.Entry<String, Class<? extends Child>> entry : fieldMap.entrySet()) {
Child child = entry.getValue().getDeclaredConstructor().newInstance();
constructorInterceptor = constructorInterceptor.andThen(FieldAccessor.ofField(entry.getKey()).setsReference(child));
}
DynamicType.Builder<Parent> typeBuilder = new ByteBuddy()
.subclass(Parent.class)
.name(Parent.class.getPackageName() + "." + config.getType())
.annotateType(Parent.class.getAnnotations())
.constructor(any())
.intercept(constructorInterceptor);
for(Map.Entry<String, Class<? extends Child>> entry : fieldMap.entrySet())
typeBuilder = typeBuilder.defineField(entry.getKey(), entry.getValue(), Modifier.PRIVATE);
DynamicType.Unloaded<Parent> unloadedType = typeBuilder.make();
return unloadedType.load(SYSTEM_CLASS_LOADER).getLoaded(); //ClassNotFoundException for Type Child
}
private Class<? extends Child> generateChildClass(ChildConfig config) {
DynamicType.Builder<Child> typeBuilder = new ByteBuddy()
.subclass(Child.class)
.name(Child.class.getPackageName() + "." + config.getName())
.annotateType(Child.class.getAnnotations());
for(Attribute attribute : config.getAttributes())
typeBuilder = typeBuilder.defineField(attribute.getName(), attribute.getTypeClass(), Modifier.PRIVATE);
DynamicType.Unloaded<Child> unloadedType = typeBuilder.make();
return unloadedType.load(SYSTEM_CLASS_LOADER).getLoaded();
}
Whenever you run unloadedType.load(SYSTEM_CLASS_LOADER), you create a new class loader. All types that are loaded within this class loader are not visible to other classes outside of it. What you can do is to merge two unloadedType values and load them together into the same class loader. Types are still available via TypeDescriptions. Alternatively, you can define a custom ClassLoadingStrategy or use a default strategy that uses injection via unsafe or via a method handle lookup (Java 9+). The load method accepts it as its second argument.

How to fix 'ArgumentCountError' while using page object model in behat

I am trying to use page object model in my behat framework . Here is my code snippet.
HomePage.php
use Behat\Behat\Context\Context;
use SensioLabs\Behat\PageObjectExtension\PageObject\Page;
class HomePage extends Page implements Context{
protected $path = '/';
}
FeatureContext.php
use Behat\Behat\Context\Context;
use SensioLabs\Behat\PageObjectExtension\PageObject\Page;
class FeatureContext extends Page implements Context, \Behat\Behat\Context\SnippetAcceptingContext
{
private $homepage;
public function __construct(HomePage $homepage)
{
$this->homepage = $homepage;
}
/**
* #Given /^(?:|I )visited (?:|the )(?P<pageName>.*?)$/
*/
public function iVisitedThe($pageName)
{
if (!isset($this->$pageName)) {
throw new \RuntimeException(sprintf('Unrecognised page: "%s".', $pageName));
}
$this->$pageName->open();
}
}
But while executing the behat tests I am getting the following error ->"ArgumentCountError: Too few arguments to function SensioLabs\Behat\PageObjectExtension\PageObject\Page::__construct(), 0 passed and at least 2 expected"
The setup should be like this:
feature > contexts > page objects
Feature file uses definitions that are defined in the context files and a Context file implements the actual step by calling actions from different page objects.
Your page object should extend just Page.
The Feature context should extend MinkContext and implement Context.
All the other contexts should just implement Context.
Ps: take a look again at the page object extension documentation on Working with page objects topic.

Xamarin Prism MasterDetailPage.IsPresented from child ViewModel

Does anyone have a clue on how to control IsPresented property from a child view model?
I'm implementing a custom NavBar where I want to simulate the Hamburger icon behavior so my child page on load has
NavigationPage.SetHasNavigationBar(this, false);
which hides the navigation par.
Inside Xaml file I have a button which I want to bind to a PropertyCommand of child viewmodel and show Master page, basically somehow to call Master's IsPresented.
Thanks.
There are a couple of ways to go about it.
The way I would do it would be to use MVVM and use an interface to access the 'presenting the Master page' functionality where its needed.
public interface ICustomMasterDetail
{
void SetMasterPresented(bool isPresented);
}
Now extend on the MasterDetailPage and also implement the above interface
public class CustomMasterDetail : MasterDetailPage, IRootMasterDetail
{
public CustomMasterDetail() : base()
{
//constructor code
}
public void SetMasterPresented(bool isPresented)
{
IsPresented = isPresented;
}
}
Using using an IoC container to register and resolve the interface will let you use its functionality from where ever you want.
The other solution would be to just use a static variable to store the instance of your MasterDetailPage and access that directly to change the IsPresented property

Decorator pattern issue - how to call nested decorators methods?

I'm now studying the decorator pattern, here some example code (PHP) :
abstract class component{
public function drawShape(){};
}
class concreteComponent extends component{
public function drawShape(){//code};
}
class decoratorComponent extends component{
private $component;
public function __construct($component){ $this->component=$component; }
public function drawShape(){
$this->component->drawShape();
}
}
class borderDecorator extends decoratorComponent{
public function drawShape(){
$this->drawBorder();
$this->component->drawShape();
}
public function setBorder(){};
public function drawBorder(){};
}
class bgColorDecorator extends decoratorComponent{
public function drawShape(){
$this->drawBgColor();
$this->component->drawShape();
}
public function setbgColor(){};
public function drawBgColor(){};
}
Ok, now:
$test=new concreteComponent();
$border=new borderDecorator($test);
$border->setBorder(10);
$bgColor= new bgColorDecorator($border);
$bgColor->setBgColor(#000);
Now I have a component decorated with a #000 bg color and a 10(some unit) border.
With
$bgColor->drawShape();
it means drawBgColor + drawBorder + drawShape and all right, BUT:
How can I modify or remove the border??
$bgColor-> ???
The bgColor class can't access directly the border methods...
Thanks
From what I understand you have chained your decorators in a way that leaves out a bgColorDecorator instance from which you cannot set/remove the borders.
What you should do is to change the order of construct and finish by the borderDecorator part :
$test=new concreteComponent();
$bgColor= new bgColorDecorator($test); // pass test to bgcolor
$bgColor->setBgColor(#000);
$border=new borderDecorator($bgColor); // pass bgcolor to border
$border->setBorder(10);
// You can now set/remove border on $border
// and of course : $border->drawShape();
It seems that your task is to render an object so the proper order of drawing should necessitate a change in your drawShape methods to keep the order background / shape / border
$this->drawBgColor();
$this->component->drawShape();
// will become a post-action
$this->component->drawShape();
$this->drawBgColor();
The problem is now you won't be able to set the backgroundcolor dynamically for the same reason. So the other solution could be to modify your decoratorComponent interface to include what you need and implement it in the decoratorComponent subclasses.
Edit for double border case :
Just chain two borderDecorator to a Component
$cmp = new concreteComponent();
$bDecrtor1 = new borderDecorator($cmp); // 1st border decorator on cmp
$bDecrtor1 ->setBorder(10);
$bDecrtor2=new borderDecorator($bDecrtor1); // 2nd border decorator on 1st one
$bDecrtor2->setBorder(20);
// $bDecrtor2->drawShape();
// You can then use bDecrtor1 or bDecrtor2 to (re)set the border properties
// You can use bDecrtor2 to chain other decorators...
What you could do is implement the magic method named __call() (a catch-all method), to try to delegate any non-existing method to the wrapped component:
class decoratorComponent extends component{
private $component;
/* ... */
public function __call( $name, $arguments ) {
return call_user_func_array( array( $this->component, $name ), $arguments );
}
}
You'll just have to build in safeguards to catch the cases where the method you're trying to call ultimately doesn't exist in any component down the line.
However, you should probably also evaluate whether it is even desirable to call the decorator methods after you have already wrapped them in another decorator.

Phalcon Initialize() is not working

I have 2 Controllers, TEST1Controller and TEST2Controller
In TEST2Controller I have a initialize() function setting value of a property.
If I try to access TEST2Controller directly from the browser, everything works perfectly.
But when I call a TEST2Controller method from TEST1Controller, it seems that initialize() function is not being called in TEST2Controller.
TEST1Controller:
namespace Modcont\Controller;
use Modcont\Controller\Test2Controller;
class Test1Controller extends BaseController
{
function gettestAction()
{
$t = new Test2Controller(); // calling TEST2 Controller Method Within TEST1 Controller
echo $t->dotestAction(" MYAPP ");
}
}
TEST2Controller:
namespace Modcont\Controller;
class Test2Controller extends BaseController
{
public $prefix;
function initialize()
{
$this->prefix = 'your name is';
}
function dotestAction($name)
{
return $this->prefix.' : '.$name;
}
}
Phalcon offers two ways for controller initialization, thy are the initialize and onContruct methods. The basic difference between these two methods is that initialize is called only when a controller is created by the framework to proceed with the execution of an action. Since you instantiating a controller object ad-hoc, initialize will not be called, only onConstruct will. So you'll need to put your initialization logic there:
function onConstruct()
{
$this->prefix = 'your name is';
}
Also, implementing native constructors in controller is discouraged, but if you do so, make sure to call the parent constructor in your own constructor: parent::__construct();.
All this information can be found in the Docs.