I want to show/hide the new link action of the admin generator list depending of some db condition.
For example:
A "Group" have many "Evaluation", a teacher may create new evaluations only if the Group status is not ended. I want to hide the "new" link of the symfony admin generator list depending on that. How can I do it?, I tried editing the _list_actions file with no success until now.
thanks.
Yoan
I think you can make it in a few ways.
You can hide link to the new action, but this is not very good,because users can create new evaluations with direct link.
So I recommend you next way.
Go to cache/backend/prod/modules/autoNamemodule/action/action.class.php
Copy to apps/backend/modules/Namemodule/action/action.class.php
next
public function executeNew(sfWebRequest $request)
{
$this->form = $this->configuration->getForm();
$this->product = $this->form->getObject();
}
Than you need to check status. I do not now yon DB table name, so for example
public function executeNew(sfWebRequest $request)
{
$id = $request->getParameter('id', false);
if (ctype_digit($id)) {
$group = Doctrine::getTable('Group')->findOneById($id);
$group_status=$group->getStatus();
if($group_status== 0){
$this->form = $this->configuration->getForm();
$this->product = $this->form->getObject();
}
else {
$this->getUser()->setFlash('notice', 'Group status ended!You can not create new evaluations ' );
$this->redirect('#yourmodulenamerout');
}
}
So if Group status ended you redirect user to the index of you backend module and show user why he can not create new evaluations). You can also hide link to the new actions. In the same way but you must make it in _list_actions file so it is not very good practice.
Related
I am trying to make a car rental agency, and in the backend I want to be able to set the rates. However there are two different (but related) ways to do this, either by individual date, or in bulk, by selecting a date range and looping over the individual dates.
In the controller I have two actions defined to do this, calendar() and bulk() respectively. I also choose the form fields yaml file to be loaded by setting the $formConfig public property. My controller looks something like this:
class AvailableCars extends Controller
{
public $formConfig = 'config_form.yaml';
public function bulk($recordId = null, $context = null)
{
$this->pageTitle = "Bulk update rates";
$model = $this->formFindModelObject($recordId);
$this->initForm($model);
}
public function calendar($recordId = null, $context = null)
{
$this->pageTitle = "Update rates for single date on calendar";
$model = $this->formFindModelObject($recordId);
$this->initForm($model);
}
public function onSave($recordId = null, $context = null)
{
$this->formFindModelObject($recordId)->save();
Flash::success("Rates saved successfully");
}
}
The problem is that this works for one of the actions, however if I put, for example:
$this->formConfig = 'alternate_fields.yaml';
in either of the bulk() or calendar() methods, it does not override the behavior and load a different form config yaml file; and it even errors out if it is not previously defined as a class property. So I can assume this yaml file is loaded before either of these methods are called.
So my question is, is there any way to load a dynamic formConfig yaml file based on the entry point? Or, is this even good practice in Laravel / October, or should each controller only be responsible to do one thing, and have only one way to create/read/update/destroy a model?
You can set configuration file manually as per your need. but we also need to follow some rules and add required methods with proper naming conventions for it.
and yes every thing is good practice if we do it properly :)
You can use this code for update existing records.
public function updatebulk($recordId = null, $context = null)
{
$this->pageTitle = "Bulk update rates";
$this->asExtension('FormController')->setConfig('bulk_config.yaml');
$this->asExtension('FormController')->update($recordId, $context);
}
public function updatebulk_onSave($recordId = null, $context = null) {
$this->asExtension('FormController')->setConfig('bulk_config.yaml');
$this->asExtension('FormController')->update_onSave($recordId, $context);
// or custom logic (if you add custom logic please remove above lines)
}
Now you can navigate to http://localhost/backend/author/plugin/controller_name/updatebulk/1 it will render form based on new bulk_config.yaml configuration file.
and when you save it, it will call updatebulk_onSave to update record. we must follow rule and let FormController handle all control to make it work correctly.
If you need to save record differently then you need to add custom logic in updatebulk_onSave method its up to you.
#Note
If you also need creation functionality you need additional methods. For ex.
public function createbulk($context = null)
{
$this->pageTitle = "Bulk create rates";
$this->asExtension('FormController')->setConfig('bulk_config.yaml');
$this->asExtension('FormController')->create($context);
}
public function createbulk_onSave($context = null) {
$this->asExtension('FormController')->setConfig('bulk_config.yaml');
$this->asExtension('FormController')->create_onSave($context);
}
if any doubts please comment.
So I have a License model created through the octoberCMS builder with the List and Form views.
The license model contains one relation to School model.
Under the Form view there is a dropdown list with schools and an input field (type=number) which defines how many Licenses to create for the chosen school.
The default behaviour creates only 1 license
How to create the entered amount of licenses instead?
You need to override default behaviour.
Note: This task require programming knowledge of OctoberCMS.
In your controller you need to add this method.
use Flash;
use Backend;
// ...
public function create_onSave($context = null)
{
// 1. init form for your modal and get input data from it
$model = $this->asExtension('FormController')->formCreateModelObject();
$model = $this->asExtension('FormController')->formExtendModel($model) ?: $model;
$this->asExtension('FormController')->initForm($model);
$form = $this->asExtension('FormController')->formGetWidget();
$data = $form->getSaveData();
// 2. get proper count field here and convert to int for loop
$count = intval($data['license_to_create']);
// 3. validation step
// if($validationFailed) {
// Flash::error('Something Went Wrong.');
// return;
// }
// 4. loop
foreach ($i = 1; $i <= $count; $i++) {
$licenseModel = new LicenseModel;
// you can add other data
// you can access $data['school_id'] here
// $licenseModel->school_id = $data['school_id'];
$licenseModel->save();
}
// 5. success message
Flash::success($count . ' License Added');
// 6. just redirect it to desired location
return Backend::redirect('/hardiksatasiya/sotest/skills');
}
Explanation
here we initialise required variables so we can get data which were filled in text box, this is default code so i just copied it from core code.
once we have our $data variable we can access filled data we use $data['license_to_create'] in your case its 100, and $data['school_id'] for which school you need to create license,
Note: you may have different fields please change accordingly.
validation step *optional, you can add some checks here and stop flow if something is not correct with error message.
loop to create new records for license modal ,[ default code will create only 1 record], but here we create it based on given count $data['license_to_create']
just normal success message.
redirect where we need to redirect normally you need to redirect it to /author-name/plugin-name/license-controller Note: you may have different url please change accordingly.
please add comment if you have any doubt.
Well actually I solved it already also by writing a custom create_onSave function for Licenses controller:
public function create_onSave(){
$quantity = post('License[_quantity]');
$school_id = post('License[school]');
for($i = 1; $i <= $quantity; $i++){
# Create License
$license = new \Acme\Plugin\Models\License();
$license->school_id = $school_id;
$license->save();
}
\Flash::success('Added '.$quantity.' Licenses');
}
I have a NewsholderPage and NewsPage. NewsPages are subpages of NewsholderPage.
I need users of a certain group to be able to create NewsPages, but not to be able to edit the NewsholderPage.
If I put the following code into the NewsholderPage...
public function canEdit($member = null){
if(permission::check('SUPERUSER')){
return true;
}
return false;
}
... then a not-admin cannot edit the NewsholderPage but also gets a "forbidden" message, when he is trying to create a NewsPage as child of the NewsholderPage.
What is the best way to allow the creation of subpages, while not allowing to edit the parent page?
You'll want to override the canAddChildren method on NewsholderPage to return something other than the default (which is simply $this->canEdit()). To get the default behaviour back, you can use something like:
public function canAddChildren($member = null) {
// Call SiteTree::canEdit rather than NewsholderPage::canEdit
return parent::canEdit($member);
}
I would like to modify two forms in one page. I generated a module with Doctrine. I have:
public function executeEdit(sfWebRequest $request)
{
$this->forward404Unless($news = Doctrine_Core::getTable('News')->find(array($request->getParameter('news_id'))), sprintf('Object news does not exist (%s).', $request->getParameter('news_id')));
$this->form = new NewsForm($news);
}
this works fine.
I added:
public function executeEdit(sfWebRequest $request)
{
$this->forward404Unless($news = Doctrine_Core::getTable('News')->find(array($request->getParameter('news_id'))), sprintf('Object news does not exist (%s).', $request->getParameter('news_id')));
$this->form = new NewsForm($news);
$this->forward404Unless($other = Doctrine_Core::getTable('Other')->findByNewsId(array($request->getParameter('other_id'))), sprintf('Object other does not exist (%s).', $request->getParameter('other_id')));
$this->form = new OtherForm($other);
}
and I get this error:
500 | Internal Server Error | sfException The "OtherForm" form only
accepts a "Other" object.
I use findByNewsId()
This works ok - if I make foreach then I have these objects, but I can't show this in the Form.
How can I achieve this?
It sounds (roughly) like you're looking to edit multiple objects within a single form - so in your example, multiple "Other" items (your question is currently slightly unclear). If so, you'll probably want to take a look at Symfony's embedded forms functionality - see this tutorial for details.
I am trying to create wish lists.
There are user and product models. A user has a wish list. A wish list has many products.
The reason I am making it user has wishlist and wishlist has products is so I can have a url like wish_lists/add/:product_id
I created a table called wish_lists with id, user_id, and name.
I also created a table called products_wish_lists with wish_list_id and product_id.
I made here is the wishlists controller:
class WishListsController extends AppController
{
var $hasOne = 'User';
var $hasMany = 'Product';
function beforeFilter()
{
parent::beforeFilter();
$this->Auth->deny('add');
}
function add($id)
{
$user = $this->Session->read("Auth.User");
$this->WishList->set(array(
'User.id' => $user['id'],
'Product.id'=>$id,
'WishList.name'=>'default'
));
if($this->WishList->save())
{
$this->Session->setFlash('This product has been added to your wishlist.', 'flash_good');
}
else
{
$this->Session->setFlash('Error: This product was not added to your wishlist.', 'flash_bad');
}
$this->redirect(array("controller"=>"products","action"=>"view",$id));
}
}
When I go to localhost/wish_lists/add/1 It tells me everytime that it saved. but no data is being added to the database.
Not sure what I am doing wrong?
I never do it that way, I always build a $data array to pass as parameter one to the save function.
I'm not sure, therefore, whether that syntax will allow you to specify the model as you have done, i.e. 'Model.field'. In any case, $this->WishList->save() will only save the Wishlist part.
Better, in my opinion, would be:
$saveData = array(
'User'=>array('id'=>$user['id']),
'Product'=>array('id'=>$id),
'WishList'=>array('name'=>'default'));
$this->WishList->saveAll($saveData);
(or something like that, I've been programming ColdFusion for the last three months and my PHP can be a bit addled)
you are setting the array wrong. it should be $data['User']['id'] = 123; $data['Product']['id'] = 321;
$this->Wishlist->saveAll($data);
There is no point saving the name as that can be found from the product table.
you can have a look at the code here for more ideas https://github.com/Infinitas-Plugins/shop
there is a generic component method in the following link that saves products to the cart or wishlist (different db's) as its pretty much the same thing.
https://github.com/Infinitas-Plugins/shop/blob/master/controllers/components/shop.php#L62