User scope with Zend Framework - oop

I'm switching a Zend Framework application from mono-user to multi-user.
What is the best approach to include the user scope in the controllers ?
One way would be to add the user id in each methods in every controllers:
/application/controllers/IndexController.php
...
public function indexAction() {
$params['user_id'] = Zend_Auth::getInstance()->getIdentity()->id;
$listHelper->readItems($params);
}
...
An other one would be to create a new User model and fetch his items :
/application/controllers/IndexController.php
...
public function indexAction() {
$userModel = new application_models_user();
$userModel->find(Zend_Auth::getInstance()->getIdentity()->id);
$userModel->readItems();
}
...
I'm wondering what's the best approach that would allow me to write minimal code and if you have another idea to "automagically" add the user scope (db scope, plugin...).

Create an abstract class by extending Zend_Controller_Action
abstract class My_Controller_Action extends Zend_Controller_Action {
private $userModel;
public function getUserModel() {
if(is_null($this->userModel)) $this->userModel = new application_models_user();
return $this->userModel;
}
public function getUserId() {
return $this->getUserModel()->find(Zend_Auth::getInstance()->getIdentity()->id);
}
}
Now use this class as base class for your controllers.

Related

How to improve factory approach to be able to register dependencies in a right way

I need a code refactoring advice. I have a class which contains several dependencies. I will just provide a constructor, but this should be enough. The class implements this interface:
public interface ITopicPublisher<T> {}
and the class itself:
public class TopicPublisher<T> : ITopicPublisher<T>
{
public TopicPublisher(IEventGridClient eventGridClient, string topicEndpoint) { ... }
}
Now, the instance of this class is injected to the Controllers like this:
public class SomeController : Controller
{
public SomeController(ITopicPublisher<MyEntity> publisher) { ... }
}
in order to create EventGridClient, I need to construct it like this (where key is a simple string):
new EventGridClient(new TopicCredentials(key))
Now, the topicEndpoint and key are taken from Environment.GetEnvironmentVariable(...). It all now is problematic when registering dependencies in ASP.NET (2.2) Startup.cs.
builder.Services
.AddScoped(x => new TopicPublisher<MyEntity>(new EventGridClient(
new TopicCredentials(Environment.GetEnvironmentVariable("KEY"))),
Environment.GetEnvironmentVariable("ENDPOINT")))
I didn't like it, so I created a factory, like this:
public class EnvironmentVariableTopicPublisherFactory
{
public static ITopicPublisher<T> Create<T>(string topicUrlEnvironmentVariable, string keyEnvironmentVariable) where T : class =>
new TopicPublisher<T>(new EventGridClient(new TopicCredentials(Environment.GetEnvironmentVariable(keyEnvironmentVariable))),
Environment.GetEnvironmentVariable(topicUrlEnvironmentVariable));
}
and now the registration process seem to be a little more simple:
builder.Services
.AddScoped(x => EnvironmentVariableTopicPublisherFactory.Create<MyEntity>("ENDPOINT", "KEY"))
I have some concerns however, that I could do it better. Could you give me some hint, how this approach can be made more clean, if this is possible?

Is there a better alternative to check for collections with members with optional interfaces?

I have a configuration registry class which holds a collection of configuration classes with a certain interface. These classes can also have an optional interface. So these classes may look like this in pseudocode:
class ConfigurationRegistry {
private ModuleConfiguration[];
public function ConfigurationRegistry(ModuleConfiguration[] collection) {
this.collection = collection;
}
public function getCollection() {
return this.collection;
}
}
class ConfigurationClass1 implements ModuleConfiguration, SpecificConfiguration {
public function moduleMethod() {
// do something
}
public function specificMethod() {
// do specific thing
}
}
class ConfigurationClass2 implements ModuleConfiguration {
public function moduleMethod() {
// do something
}
}
public interface ModuleConfiguration {
public function moduleMethod();
}
public interface SpecificConfiguration {
public function specificMethod();
}
In my client code I would like to use these configuration classes. Sometimes I need the whole collection of configuration classes and sometimes I only need to collection of configuration classes which implement the SpecificConfiguration interface.
I could filter the collection method by using instanceof or I could loop through the collection and check whether the class implements the interface. But I've read quite a few articles stating online that using instanceof in this case is not considered a good practice.
My question is: is my implementation a good design? If not, do you have any suggestions how I could redesign or improve this?

Nhibernate and decapsulating decorators

I am currently working on a project with NHibernate that requires security and auditing aspects. Those two seem to be perfect fits for the decorator pattern. Therefore my first step was to extract an interface for the entities to be decorated. Next, I decorated the relevant repositories to return decorated entities that implement the required auditing and security respectively. This works as expected.
However, a problem arises when NHibernate is asked to save a decorator instead of the base entity. Consider the following model as a simple example. It consists of an Engine that can be composed from multiple components.
public interface IEngine {
void AddComponent(IComponent component);
// Other Engine methods
}
public interface IComponent {
// Component methods
}
// Component basic entity mapped via NHibernate
public class Component : IComponent {
}
// Engine basic entity mapped via NHibernate
public class Engine {
private IList<IComponent> _components;
public Engine(IEnumerable<IComponent> components) {
_components = components.ToList();
}
public void AddComponent(IComponent component) {
_components.Add(component);
}
// Other engine methods
}
// Component security decorator
public class SecurityComponent : IComponent {
private readonly IComponent _innerComponent;
public SecurityComponent(IComponent innerComponent) {
_innerComponent = innerComponent;
}
// delegated and changed methods
}
// Engine security decorator
public class SecurityEngine {
private readonly IEngine _innerEngine;
public SecurityEngine(IEngine innerEngine) {
_innerEngine = innerEngine;
}
// delegated and changed methods
}
The code that is responsible for creating and saving Engines does not know anything about security decorators:
var components = componentRepository.RetrieveMatchingComponents(); // because the repository is decorated, this method returns SecurityComponents
var engine = new Engine(components);
engineRepository.Create(engine); // will fail because NHibernate cannot deal with the decorators referenced in the Engine
The only solution I can currently think of is to move the object creation into a factory that can also be decorated by the security code. The security factory would
need to decapsulate the SecurityComponents in order to construct a inner engine consisting only of basic entities. In addition the SecurityEngine would need to
decapsulate all incoming SecurityComponents. Finally the SecurityEngineRepository would need to decapsulate incoming SecurityEngines so that the innermost repository
that calls Session.Save receives only a basic entity Engine consisting only of basic entity Components. For example:
public class SecurityComponent : IComponent {
private readonly IComponent _innerComponent;
public SecurityComponent(IComponent innerComponent) {
_innerComponent = innerComponent;
}
public IComponent Decapsulate() { return _innerComponent; }
// delegated and changed methods
}
public class SecurityEngine {
private readonly IEngine _innerEngine;
public SecurityEngine(IEngine innerEngine) {
_innerEngine = innerEngine;
}
public void AddComponent(IComponent component) {
// do security stuff (e.g check if adding components is allowed)
IComponent result;
if (component is SecurityComponent) {
result = ((SecurityComponent)component).Decapsulate();
} else {
result = component;
}
_components.Add(result);
}
// other delegated and changed methods
}
public interface IEngineFactory {
IEngine CreateEngine(IEnumerable<IComponent> components);
}
public class EngineFactory : IEngineFactory {
public IEngine CreateEngine(IEnumerable<IComponent> components) { return new Engine(components); }
}
public class SecurityEngineFactory : IEngineFactory {
// decorator constructor
public IEngine CreateEngine(IEnumerable<IComponent> components) {
// decapsulate security components
var innerEngine = _innerEngineFactory.CreateEngine(decapsulatedComponents);
return new SecurityEngine(innerEngine);
}
}
The engine construction code:
var components = componentRepository.RetrieveMatchingComponents(); // because the repository is decorated, this method returns SecurityComponents
var engine = engineFactory.CreateEngine(components); // SecurityEngineFactory will return a SecurityEngine with a well formed inner Engine
engineRepository.Create(engine); // SecurityEngineRepository will decapsulate the SecurityEngine
This solution seems like a code smell to me. Is there a general pattern to solve this problem? Any suggestions on how to improve this solution?

Laravel Read User id in Controller constructor

In my controller(s), instead of fetchingAuth::id() in each method, I've set up an $id property in the controller's class and fetched it once in the constructor. then, in the rest of the methods i'm just refering $this->id, is it considered safe or am I doing something wrong?
Code Sample: http://pastebin.com/pvju54eh
What you could do is inject the Guard instance in your controller and then assign the currently logged in user (if there is one) to a class property:
<?php namespace App\Http\Controllers;
use Illuminate\Contracts\Auth\Guard;
class SomeController extends Controller
{
protected $auth;
protected $user;
public function __construct(Guard $auth)
{
$this->auth = $auth;
$this->user = $this->auth->user();
}
public function someMethod()
{
// Get logged in user’s ID
$userId = $this->user->id;
}
}
I do not see any major problems with this approach even though I have not seen approach used often.
Myself I find it easier to get the $request->user() in controller from Request though.

Laravel Eloquent, return JSON with "belongsTo" object?

I have two models with a one-to-many relationship.
class User extends ConfideUser {
public function shouts()
{
return $this->hasMany('Shout');
}
}
class Shout extends Eloquent {
public function users()
{
return $this->belongsTo('User');
}
}
This seem to work fine.
BUT, How do I get this to return the users object nested in the shout objects?
Right now it only returns all my Shouts, but I have no access in the JSON to the belonging user model.
Route::get('api/shout', function() {
return Shout::with('users')->get();
});
This just returns this JSON, with no user object for every shout:
[{"id":"1","user_id":"1","message":"A little test shout!","location":"K","created_at":"2013-05-23 19:51:44","updated_at":"2013-05-23 19:51:44"},{"id":"2","user_id":"1","message":"And here is an other shout that is a little bit longer...","location":"S","created_at":"2013-05-23 19:51:44","updated_at":"2013-05-23 19:51:44"}]
I was having the same trouble using Laravel 5. Just wanted to add that I got it to work by using the Model::with("relationship")->get() method on the model.
I figured it out.
The method needs to be named user() not users() when working with "belongsTo" relationship.
Makes sense.
And seems to work.
If you are using:
protected $visible = ['user'];
Don't forget to add there relationship, to be visible in JSON
u can use protected $with = ['users']; on Class Shout and use protected $with = ['shouts'];.
and Give Full namespace model name
class Shout extends Eloquent {
protected $with = ['users'];
public function users()
{
return $this->belongsTo('App\User');
}
}
and
class User extends ConfideUser {
protected $with = ['shouts'];
public function shouts()
{
return $this->hasMany('App\Shout');
}
}
Receive It
Route::get('api/shout', function() {
return Shout::all()->toJson;
});