CakePHP add method confused - php

On my CakePHP site I use a table called portfolio I tell Cake this in the model to get around the automated plural nonsense with the following code:
class Portfolio extends AppModel
{
var $name = 'Portfolio';
var $useTable = 'portfolio';
}
This works fine except when trying to add a new portfolio item as even though the url is fine at /portfolio/add/ the form itself has an action of /portfolios/add/ which breaks the app.
How do I fix this?

it's much better and easier to follow CakePHP conventions
that would save you a lot of time !!
your problem is just an example..
by time, you will face more similar problems !!
i strongly recommend that you follow the conventions of CakePHP
one of them is "use plural names for tables"

Ended up hacking it like so:
echo $this->Form->create(null, array('url' => array('controller' => 'portfolio', 'action' => 'add')));
Really hate how CakePHP adds a dam s to everything!

Related

Can't do the CakePHP autocomplete tutorial

In CakePHP, I am trying to create a autocomplete function from a textbox, using this tutorial: http://bakery.cakephp.org/articles/matt_1/2011/08/07/yet_another_jquery_autocomplete_helper_2
I keep getting a
Error: AutoCompleteHelper could not be found.
Undefined index: autoCompleteText
I am unsure how to fix this as I have tried relocating the files and still the same error.
I create the below files and copy the code from the tutorial,
create the auto_complete.php in the view/helpers directory,
and create webroot/js/views/helpers/auto_complete.js.
controller - Tests
function auto_complete
class TestsController extends AppController {
public $helpers = array('Html', 'Form', 'Session','Js','AutoComplete');
public function auto_complete() {
$this->loadModel('Tutor');
debug( $this->params);
$terms = $this->Tutor->find('all', array(
'conditions' => array(
'Tutor.first_name LIKE' => $this->params['url']['autoCompleteText'].'%'
),
'fields' => array('Tutor.first_name'),
'limit' => 3,
'recursive'=>-1,
));
$terms = Set::Extract($terms,'{n}.Tutor.first_name');
$this->set('terms', $terms);
$this->layout = '';
}
view
auto_complete.ctp
<?php
echo $this->AutoComplete->input(
'Tutor.first_name',
array(
'autoCompleteUrl'=>$this->Html->url(
array(
'controller'=>'tests',
'action'=>'auto_complete',
)
),
'autoCompleteRequestItem'=>'autoCompleteText',
)
);
if(isset($terms)) {
echo $this->Js->object($terms);
}
echo $this->Form->create('');
echo $this->Form->input('type', array('label' => 'Choose' ));
echo $this->Form->end('send');
?>
I had a good look around previous posts and I really couldnt solve the problem.
Cakephp form input with autocomplete
The tutorial you're looking at is for CakePHP 1.x (it's from August 2011, Cake 2 came out in October '11), but you're running Cake 2.5. The naming standards have changed between 1.x and 2.x, so Cake can't see your helper.
First: Your main problem is that you're naming your helper auto_complete.php when it should be AutoCompleteHelper.php.
Second, you are placing it in the wrong directory. In Cake 1.x, helpers lived under /view/helpers/. In 2.x, they live under /View/Helper/.
Third, regarding the undefined index error, you need to understand how this helper works in the first place, and why you're implementing it incorrectly.
The controller action auto_complete should not have a view. It's just a data source. When you use the helper, it loads the Javascript, which does its magic by polling /auto_complete?autoCompleteText=stringgoeshere.
You might notice that you removed $this->layout = 'ajax'; from the controller action, probably because your toolbars weren't rendering. They weren't supposed to. It's just a datasource, it NEEDS the ajax layout, and there should be no view on that action.
Because you were trying to put a form on your auto_complete action and not on another action, the helper was looking for the query parameter autoCompleteText, not finding it, and displaying an error.
You can solve this by changing the auto_complete action back as close as possible to how it was in the example, deleting auto_complete.ctp, and by trying to use the helper in the correct view, like add.ctp.
Fourth: You shouldn't be using jsHelper anymore. It's been deprecated in 2.5 and is going to disappear in the future. Basically, the tutorial is obsolete.
However, it's really easy to just replace $this->set('terms', $terms); with return json_encode($terms) and write your own piece of JS to make an AJAX call. I suggest incorporating Typeahead.js.
Finally: You should consult the 1.x -> 2.x migration guide, and as well, once you get your helper running you've got some other typos in your code that will break it anyway- "Ttuor.first_name", for example. Good luck!

Loading a new page in yii

I'm trying link the form I created in yii, and make it to go to another page. However since I'm new to yii, I'm confused if it's calling the controller, model or view, plus I dont have a clue where the rendering of the new page should be placed.
I've just taken over someone's work and I'm still studying the yii framework itself.
The code for the form is:
<?php $form=$this->beginWidget('CActiveForm', array('id'=>'apply-form','action' =>
'/site/apply','enableAjaxValidation'=>false,'htmlOptions' => array('enctype' => 'multipart/form-data'),)); ?>
and for the site controller its
public function actionApply()
{
$model = new ApplyForm;
if(isset($_POST['ApplyForm']))
{
$model->attributes=$_POST['ApplyForm'];
$stringsubject ="Application for Crunch Marketing-".$_POST['ApplyForm']['fieldName'];
$model->subject = $stringsubject;
if($model->validate())
{
$mailer = new EmailSender();
$success = $mailer->send($model, 'test#crunch.com.ph');
}
}
$this->render('index',array(
'contactModel' => new ContactForm,
'applyModel' => $model,
));
}
I dont know how the flow actually works. I'm used to the standard form action call, so I'm really confused.
The answer is very broad.
To have idea about fundamental things in yii this is good article I came by through:
http://www.larryullman.com/2009/10/31/getting-started-with-the-yii-framework/
Read the whole series.
May it helps to clear the flow.
Firts you need read this:
http://www.yiiframework.com/doc/guide/1.1/en/basics.mvc and all fundamentals
Your form is send '/site/apply' , site is the controller and apply is a controller action, this action render the view site/index

Set a form_validation rule from a library in CodeIgniter (PHP)

Ok so i've got a big problem with CodeIgniter flexibility. I've many personal rules (like 20) targeting an input in a form within a huge project.
Everything work while I use the classic "callback_" system by CodeIgniter. I just put the methods in the same class than the form check and it checks it correctly.
My problem is :
1) I'd like to use all these rules in another form_validation in another controller without copy/paste the code ; we all know it's dirty/evil.
2) Ideally, i'd appreciate to put these rules in a big library, because it takes something like 800 lines and this is not a good idea to let it be in my controller ; as I said this project is quite huge.
It's 6 hours i'm looking for a solution and there's absolutely nothing clean :
I already have a MY_Form_Validation to put some general rules but i don't like the idea to mix my specific rules in a global class which will call it everytime vainly. Plus these rules contain many libraries, models, native CI core methods such as $this->input->post() which generate errors when I put everything in this MY_Form_Validation. Not the good solution :(
I created a MY_Controller including a method named 'imports' which re-generate selected libraries methods within the controller (in PHP4 it was kind of the 'aggregate_methods' function if people are curious) ; the system works perfectly but CodeIgniter doesn't understand it. The methods can be called within the controller but it seems the framework check the $CI content to call the rules (Form_validation.php line 590 in '/system/') so it doesn't work at the end ; it's also hard to modify this core part, I prefered not touching it and gave up.
$this->load->library('volt/lbl_validation');
$this->imports('Lbl_validation');
// Then you can call any $this->lbl_validation->method() with $this->method() in the controller
I tried to hack CI creating a customized form_validation within my library ('lbl_validation') ; the system was a bit messy but worked. The problem is when i came back to the CI form_validation system to show error messages, it was a true spaghetti-code which wasn't working that well. Not the good solution either.
I also tried some other shitty solutions but i prefer not confess it.
Now i'm here in front of my computer asking myself why bad things happened to good people, why this is so hard to separate set_rules from the called methods in CodeIgniter, why they didn't plan ahead people could've needed to call libraries methods as rules. I don't know what to do and i'm hesitating to put a dumb require() somewhere and make it all dirty and messy like my desk right now.
Maybe, there's someone with a good dans clean solution. All my hope are turned to the StackOverFlow community ; someone ? A crazy CI geek ?
Thank you ;)
The only good, DRY way to handle validation is to put validation rules at the last resort before saving to the the database, in other words in the models. By doing this, the same rules can be used in any controller or library without being redefined.
The following idea is taken from Jamie Rumbelows excellent Codeigniter handbook:
Simply create an array in your model:
$validate = array(
array( 'field' => 'username', 'label' => 'Username', 'rules' => 'required,trim' ),
array( 'field' => 'password', 'label' => 'Password', 'rules' => 'required|min_length[8]' )
);
Then implement a method that you can use to validate your data prior to save()
function validate($data) {
if (!empty($this->validate)) {
foreach ($data as $key => $value) {
$_POST[$key] = $value;
}
$this->load->library('form_validation');
$this->form_validation->set_rules($this->validate);
return $this->form_validation->run();
}
else
{
return TRUE;
}
}
Now, in your controllers you can use:
if ($this->user->validate($user))
save...

Create a dashboard in Yii Framework

I am newbie to yii. I am doing a small application in Yii.
Lets suppose I have some tables like product, sales, discount, customer,
Now I have done all the Models and Controllers(crud) for these tables. Now when admin wants to enter one new product then he is typing
http://localhost/application/index.php?r=product
. In the same way he has to enter discount to go discount section. Now I want to render all the modules in one application just like dashboard. Where admin can directly make change what he wants from that single page. So can someone kindly tell me how to solve this issue. Any help and suggestions will be really appreciable.
EDIT
I have gone through some links but I did not found any documentation there.
First of all you should think of what should be presented on dashboard, you have choosen some entities already. From that entities there might be different criteria for showing items:
One will show latest products
Other will show last edited posts by user
And maybe sales will show highest sales?
Now, you should choose whenever to allow some actions on theese items.
For product you could have some (sample) quick buttons/link: publish, update
For customer there could be orders
Now, to acomplish this, you would have to define several dataproviders, setup several listviews, and put all that into your DashboardController. No! From Yii conventions, and MVC generally, there should be: fat model, this controller, and wise view.
Taking above into account, you should create widget for each type of data. Widget should be "independent", this will be like "model" for your dashboard. Should contain all logic required for type of entity, and should not require any configuration (for autocreation too).
For dashboard widget you should also create some base class for this purpose, so dashboard widget will look consistently: to have some layout.
A good start for this purpose is CPortLet - this already defines somethink like dashboard widget, with title, and div around it's content.
Here is some example to start with portlets:
class ProductDashboard extends CPortlet // Or intermediate class, ie. DashboardItem
{
protected $_products = array();
public function init()
{
$this->_products = new CActiveDataProvider('Product', array(
'criteria'=>array(
'with'=>array('...'),
'order'=>'t.sort_order ASC',
'condition'=>'...',
'together'=>true,
),
));;
$this->title= 'Newset producs';
parent::init();
}
protected function renderContent()
{
$this->render('productDashboard');
}
}
In portlet view, views/productDashboard.php just place listview:
$this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_productView',
'enablePagination'=>true,
));
In _productView place anything about product:
<h4><?= CHtml::encode($data->name); ?></h4>
<p><?= CHtml::encode($data->description); ?></p>
<p>
<?= CHtml::link('Update', array('/product/update', 'id' => $data->id)); ?>
<?= CHtml::link('View', array('/product/view', 'id' => $data->id)); ?>
... More actions ...
</p>
Finally in your dashboard index view place those portlets:
$this->widget('path.to.ProductDashboard');
$this->widget('path.to.SalesDashboard');
....
Or in some automated way:
// Possibly user defined only etc.
$widgets = array('ProductDashboard', 'SalesDashboard', ...);
foreach($widgets as $name)
$this->widget($name)
First, lets take a look on this. Uh, almost 200 pages, but let me leave it here and refer to it in the following answer.
So, we want a page that can manage edit/delete/update actions with the table, and Yii can help you with it in 2 ways:
1st Is for lazy codders, or a guys who just start to work with framework. Just go to the documentation and find out the 1.6 Creating First Yii Application. This article will helps you to set up the basic configurations with demo models/views/controllers to play with it. The result of this Demo Installation is like your dashboard required with more features to explore
2nd step require a lot of code to show up here, and it will be just an instruction how to build everything step-by-step that you can do in the 1st step automatically with Yii. Just ask if you'd like to know about it more.
Cheers!
It sounds like you want to implement a menu. Assuming that you have at least gone through the Creating First Yii Application mentioned by Ignat B., you can read the CMenu class documentation to learn about them, and your modifications would go in the layout.php file in protected\views.
If its a list of menu that you are looking for, you might try this extension: http://www.yiiframework.com/extension/emetrotile
All you need to do is follow the instructions in the source then call it where you want it to load similar to the one below:
$this->widget('ext.emetrotile.EMetroTile', array(
'Tiles'=>array(
array('title'=>'Test Title', 'tiles'=>array(
array('content'=>array('test1-a','test1-b'), 'liveTileOptions'=>array('data-speed'=>750, 'data-delay'=>3000,'data-stack'=>true)),
array('content'=>'test2', 'position'=>'bottom'),
array('content'=>'test4', 'position'=>'bottom'),
array('content'=>'Blog', 'style'=>'vertical', 'url'=>'http://blog.expressthisout.com'),
array('content'=>'test3', 'style'=>'horizontal'),
array('content'=>'test5', 'position'=>'bottom'),
array('content'=>'test6', 'position'=>'top'),
))
)
));
As Syakur Rahman says, emetrotile is a good extension for creating a dashboard. I've created a nice 3 x 2 menu with it, with an image on the front of each, text on the back, and they flip in a sequence one after the other. It has a very cool effect, but it does have a Windows feel to it.
Drew Green wrote the original js seems to be improving it all the time, See http://www.drewgreenwell.com/projects/metrojs

Implement a search using zend

I have site which is managed using CMS entirely developed on zend. Now I have to Implement a search feature too. I'vent done anything related to search in zend. Some suggestions that I received is to implement a spider. The site will have plenty of links(and it will keep on adding). I'm totally confused and I don't know where to start from. Will zend_search_lucene do the trick?
You probably aren't going to find something completely turnkey for this. If your content is all public, and you are fine with just using a crawler, the easiest thing to implement could be Google Site Search.
http://www.google.com/enterprise/search/products_gss.html
If you need to get different functionality out of the search that this wouldn't offer, you'll likely be stuck doing some code. The Zend Lucene link that Alvar posted is good. One of the ugly things about Zend_Lucene, if I am not mistaken, is that it's relying on the text based lucene indexes without any Java. It's just slower and more cumbersome to manage.
A more robust Lucene based approach is Solr. It's Java based, and runs on it's own service with an API. It scales well, and there's a PHP Pecl out now that will help you communicate with it.
See http://php.net/manual/en/book.solr.php
Another option is Sphinx. This search engine bolts directly to your database, so indexing might be a little more intuitive.
http://sphinxsearch.com/
Good luck to you!
Lucene is strange, i never got it to work properly and developed my own search logic, but maybe this helps:
http://devzone.zend.com/397/roll-your-own-search-engine-with-zend_search_lucene/
Because you are using a home grown product you'll likely be better served by keeping things as simple as possible, at least in the beginning. Also because you're product is home grown you should have a pretty good handle on the data structure.
Building a simple query based search may be something appropriate for starters.
I started with a simple search form:
<?php
class Application_Form_Search extends Zend_Form
{
public function init() {
$this->setMethod('POST');
$this->setDecorators(array(
array('ViewScript', array(
'viewScript' => '_searchForm.phtml'
))
));
// create new element
$query = $this->createElement('text', 'query');
// element options
$query->setLabel('Search Keywords');
$query->setAttribs(array('placeholder' => 'Title',
'size' => 27,
));
// add the element to the form
$this->addElement($query);
$submit = $this->createElement('submit', 'search');
$submit->setLabel('Search Site');
$submit->setDecorators(array('ViewHelper'));
$this->addElement($submit);
}
}
then I built a simple action helper to display and route the form:
<?php
class Library_Controller_Action_Helper_Search extends Zend_Controller_Action_Helper_Abstract
{
public function direct($action, $label = null, $placeHolder = null)
{
$form = new Application_Form_Search();
$form->setAction($action);
$form->search->setLabel($label);
$form->query->setAttribs(array('placeholder' => $placeHolder,
'size' => 27,
));
return $form;
}
}
then I added a placeholder for the search form in my layout.phtml
<?php echo $this->layout()->search ?>
then in the controllers that need to use the search function I add the helper to predispatch():
public function preDispatch()
{
//assign search action helper to view placeholder
$this->_helper->layout()->search = $this->_helper->search(
'url_for_action', 'Submit button label', 'placeholder text'
);
}
then I use a simple mapper method to perform the appropriate query and I usually return a paginator adapter:
public function fetchPagedMoviesByTitle($title)
{
$select = $this->getGateway()->select();
$select->where(new Zend_Db_Expr("title LIKE '%$title%'"));
$select->order('title', 'ASC');
//create a new instance of the paginator adapter and return it
$adapter = new Video_Model_Paginator_Video($select);
return $adapter;
}
This is simple way to implement a search function and is adaptable to most types of queries. I find that a switch statment and a couple of simple database queries and almost any information I need is available.
Good Luck.

Categories