I'm thinking of creating admin page with forms to modify, delete and add content to simple pages of website. What would you recommend me to approach this in Symfony2?
Should I create new Bundle or just new Action in same controller where all the other pages are.
I heard of this SonataAdmin, but I am not sure I need something this complicated. My admin page will only contain few forms to modify some data that is stored on website. I don't need CMS functionality to create pages or posts.
All I want is simple, safe admin page and to know how nowadays this problem is solved.
Just create something like a AdminBundle and create your forms there.
Secure your routes so that you need to login to acces that routes.
SonataAdmin is to much for this kind of work.
Example of a secured function where you need to be logged in as admin :
/**
* #Route("/", name="homepage", name="homepage")
* #Route("/{_locale}", name="homepage", name="homepage")
* #Security("has_role('ROLE_ADMIN')")
* #Template("ProdacomMainBundle:Main:index.html.twig")
*/
public function indexAction() {
return array();
}
It looks like you really don't need SonataAdminBundle. It's huge and sometime difficult to understand. So, for such functionality you can create some secured area in your routing and use to access management pages. Or you can implement simple authentication with hardcoded (inside config files) credentials (look detailed description here: http://symfony.com/doc/current/book/security.html) and show for authenticated user additional elements on the pages (forms, buttons, etc.). It really depends on your wishes. I think you have to overthink all you have and just decide which way is more convenient for you.
Related
I readed doku and search about middleware on october informations, but nothing find what me can help.
My Problem:
I created Plugin and use RainLab User Plugin for Frontend Editoring of Content.
Frontend Content spilt up on Section, Group and Article.
Single Users become different access: hiddem, show, edit and more for sections and articles.
The site works with one plugin on content load dynamic.
How i can load content for single user by access config?
My solution:
I added on backend some functions to give access for users.
rainlab user content access
All access configs saved and works.
My idee is to create middleware to load content but i find nothing what can help me.
Docu tell me you can create middleware but middleware load all time on frontend, backend, all pages on website. This is not good solution.
https://octobercms.com/docs/backend/controllers-ajax#controller-middleware
In addition comes if i debug on middleware, so rainlab user functions not working, no informations about url request.
Why add middleware when you must load and create all classes and functions by himself??
I need middleware only for frontend and only for plugin or component.
I hope somebody can me help to find another solution or idee to fix it.
I think there is nothing left but to implement the content access in respective component on onRun function. :( and problem by this solution is: return Redirect not working outside a class or function (only on onRun)
There is Problem with your approach, as you want middleware and also you want to make sure it run for specific plugins and component. middleware worked based on request and request may have information about URL etc. but not about plugin & component etc so it can not determine when to run based on plugin etc..`
So you may use Different approach. and it will work with Frontend also with ajax requests.
You can create component inside your plugin, It will assessment all the access for logged in user if user is logged in. if user is not logged in you can provide different assessment access.
Now you need to add this component to your layout and now all pages which are using this layout have this access information from the beginning.
Now this component inject access information to page, So your Page and plugin's components can have this information readily available. now from your component inside onRun you can handle redirect at very top.
Component is not to define access, its just inject predefined access information which is in database [ as you said you use users plugin so fetch it and inject it ] to the page
Component will be specifically just inject access information to page. And that Component will be on layout so. it will automatically trigger for that layout pages. so it will executed first and based on that you can decide how to use it. you can also render conditional component based on that. as you can have access information in markup part as well so
if you have any doubt or questions please comment.
Our Symfony application is currently one application, that will soon require ability to have multiple sites point to the same Symfony core and have slightly different functionality based on which site it is currently on.
As an example we might have a banner showing on one site but not another. Another example is a payment option that will be enabled/disabled on the different sites. Or another one is different fields on a form on the different sites.
Has anybody had experience structuring Symfony application in this way?
If you want to "theme" your application you can use the LiipThemeBundle, it really works well. For the features activation/deactivation you also have the FeatureToggleBundle bundle (quiet recent).
You could also implement a basic helper like this:
/**
* Check if a feature is activated.
*
* #param string $feature Name of the feature
*
* #throws AccessDeniedHttpException
*/
protected function checkFeature($feature)
{
$features = $this->container->getParameter('app.features')
if (!$features[$feature]) {
throw new AccessDeniedHttpException();
}
}
...
$this->checkFeature('contact_form');
With this kind of configuration:
app.features:
contact_form: false
You have to know that using kernel event listener you can do most of the work.
You can in a 'CoreBundle' for example refer the user to a different template depending on the domain name where he is, using the kernel.request event.
So in your situation it would be easy for a site to showing a banner in a site but not another.
You can look this article that explains it :
Twig templating using event listener
Yess thats the advantage of symfony
symfony use the kernel connected with routing and controller and then response is being created.
If you want to use multiple applications in symfony you can do this very easily and that is an advantage of symfony.For this you just need to add some routing and everything will be done automatically.
You can use symfony form class to add forms and append them to other pages with required field without creating whole form again.
If you want to add or remove some features on/off you can just do this by app class or by creating different controllers.
I am building a Laravel 4 application and I am trying to sort out where my admin controller functions should go.
eg my admin user view, edit and update functions.
Previously in my User controller, I would have
function getIndex()
{
// Get method for normal users
}
function getAdminIndex()
{
// Get method for admin users
}
I would then have in the routes /users -> getIndex() and /admin/users -> getAdminIndex()
however, is this ideal?
The reason is it makes my routes file quite large as I have to specify every route.
With things like Blog posts, and Products, should I have one controller for logged out / user access, and then a separate controller, in an admin folder for just the admin functions?
Is there some open source projects I can look at?
You should separate your regular controllers from your admin controllers. It's a matter of personal preference how you do it: you can create folders inside your controllers folder, or maybe you could create –almost– independent modules with controllers on their own.
For the first option, take a look at this project:
https://github.com/andrew13/Laravel-4-Bootstrap-Starter-Site
For the second one, which is a bit more complex, you can get inspired from this post by Ryan Tablada:
http://ryantablada.com/post/juggling-larger-laravel-applications
I personally prefer this last one if the project is medium/large size, and the other one if it's a small project.
You can also try Laravella, a CMS, CRUD, Bootstrap, Uploader etc. framework for Laravel.
https://github.com/laravella/laravella/releases
If your project is small, then you can use Resource Controller.
I'm new to Codeigniter and pretty new to OOP as of the last month or so. I've been playing around and have been trying to make a blog page with a list of 10 posts and have different functions and possibilities for each.
For example, in the future I want to be able to show different buttons below posts depending on whether they are a logged in user, or if they are the post creator, etc.
Would I be best off making a new class 'blog_posts' and making an instance of it for every post I show on the page? like:
$this->load->library('blog_posts'); // in library or models, I'm not too sure?
$new_inst = new blog_posts;
$new_inst->show_post();
My end goal is to get it all as easily updated, changed, or modified in future if needed, I've seen simple tutorials online:
http://blog.pisyek.com/2011/03/create-a-simple-blog-using-codeigniter-2-0-part-1/
But I can't see them being easily updated and modified in future. I haven't seen a lot of other CI apps using new instances of classes, so I'm thinking there may be a different way in CI? Are new instances used in CI a lot?
Start with the controller. With Codeigniter -- anything you can do in a model, you can do in the controller. The easiest way to start -- just put your methods in the controller and set up a simple view file.
Always do a simple sanity check to make sure the basics are proper. Set up a controller and echo out some text.
In the controller try:
Get blog posts from your database using active record commands
Pass the blog posts result to $Data
With each step, Echo out something in the controller to confirm that its working
Next -- try using $Data to pass the blog results to the view.
After its working and you understand the basics -- then start pushing your methods to a Model. As you refactor and clean, your controller will get 'thinner'.
typically for blog posts you would have one model, that would return the blog posts and might also have your insert / update / delete methods. i say might because it usually makes more sense to have a public blog controller, that just shows blog posts. and then a separate blog admin controller -- that is only available to users who are logged in.
These two controllers - can share the same blog model. So for example to show blog posts on an admin screen - you could use the same method as showing the posts on a public page. Whereas you might have an admin blog model -- which has the create / update / delete methods.
That way you enforce a very clear separation of User Roles from the start -- people who are viewing the public blog should not be able to delete posts. The public show blog class is not "responsible" for editing.
This is something that i'm grappling with -- like the normal way to demonstrate a blog is to have all the methods together. Which makes sense in terms of "what can we do with a blog post" -- but it doesn't make any sense in terms of user roles.
ok Next - work on your create and update and delete methods.
Next try creating your log in methods. Make the Login process separate controller / model / view.
Eventually you could have one method call in the constructor of your blog admin class that checks to make sure that the user is logged in - otherwise it redirects them to a login page. That way you dont have to check over and over again in the view files etc to make sure they are authorized.
( highly recommend the free codeigniter tutorial series on net tuts website )
more rambling:
looking at the process from the point of view of the actor (user,role) -- for me helps to clarify what the chain of control should be. really critical roles - like an admin that has the power to delete all blog posts - the system should know that role at the top of the class.
best 'worst example' is when there are "is this a super admin?" checks in the view code. the view should not know anything about admin roles. BUT MUCH WORSE when you put a reference to an admin role in some view file -- what happens when you want to change that admin role in some way? now you have to go into all your view files!
class and method names - i'm moving towards not revealing any business or crud or field or any other type of business information in the URL. no nouns no verbs no ids. as simple as possible, with very few public url 'doors' into the app.
whats wonderful is that codeigniter makes it really easy to make your methods private. for critical pages: only use the public index method in the class for redirecting and make all other methods private.
use routes that directly to private methods. or public methods with broad names, that if successful -- like you have confirmed their credentials - go to private methods in the class like $this->_showAdminPage()
this is where defining a role like - blog editor - makes things very clear from a functionality point of view, AND keeps the valuable business knowledge private.
I'm working on an app in CodeIgniter, and I want to have admin pages for several of the objects in the application, and I'm wondering what would be the better way to put these into an MVC structure.
Idea 1:
In each controller, have an admin function, and add all of the admin pages I would like into that function.
example URL: domain.com/articles/admin
Idea 2
Make a new admin controller, which would have to reference many different models, and put all of the admin pages in there.
example URL: domain.com/admin/articles
Which way would be better?
Edit for clarification: By admin functionality, I mean being able to do the basic CRUD actions on any object, and be able to display a list of all of said object.
Definitely a different controller at least!
I used to think that I could keep all my admin functions in a single controller, but as my programs grew, I realized that I needed multiple controllers in my administration section.
So, I created a folder inside my controllers folder with the name "admin" and put all my administrative controllers in there. So my folders would look something like:
application
controllers
front.php
welcome.php
admin
dashboard.php
useradmin.php
etc...
One problem this creates, however, is when you type http://mysite.com/admin in your browser, it returns a 404 page. So, go to your "application/config/routes.php" file and add a custom route:
$routes['admin'] = 'admin/dashboard/index';
I'll echo Justin in keeping it part of the individual controllers.
You should setup some kind of authorization system that the individual controllers can use to so who is logged in (username) and what access they have (admin/member/etc). Here's a SO thread on CodeIgniter Auth Classes.
The view would then conditionally show the appropriate links, and the controller would enforce the policy by checking the auth before passing any data to the model or rendering an edit view. On unauthorized access an error could be rendered, or simply render with the non-editing view.
This approach seems to make the most sense (at least to me) because all the functionality is stored in the individual controller. Keeping admin functions in a single admin controller means you'll have to manage two controllers (the admin, and the actual controller) every time you add somethign new (or remove something).
If you're concerned about putting auth checking in every controller, you could create a generic controller class with all the auth setup, then have your controllers extend it. In the end the individual controller auth check could be as simple as:
function edit()
{
if(!$this->auth()){
//display auth error, or forward to view page
}
}
Of course some kind of ACL implementation would make this better, but I don't believe CodeIgniter has an 'official' ACL.
It's a good idea to have an admin folder in the controllers folder wherein you can access your administration e.g. yoursite.com/admin/users.
All your administrative needs will be there and all methods will be protected by checking user privileges like so:
if ( ! $this->auth->logged_in(array('login', 'admin')))
{
$this->session->set_flashdata('message', 'You do not have access to view this page');
redirect('admin/users/login');
}
Then all controllers outside the 'admin' folder will - depending on your type of site - will only be for viewing, etc.. no administrative portions.
Idea 2 is better.
system/application/controllers/admin
You keep all your admin controllers here.
Here is an extensive guide to the pro's and con's of each method:
http://philsturgeon.co.uk/news/2009/07/Create-an-Admin-panel-with-CodeIgniter
Depending on what you mean by 'Admin' functionality...typically, this is thought of as an 'Edit' view.
And typically, you use the existing controller to serve the 'Edit' view allowing the authorized users to make the edits (in your case, Admin users only).
Looks like a personal choice, i love having everything centralized so the admin controller would be my bet.
That way i wouldn't have to open up 5 different controllers while modifying admin tasks.