I've been trying, but in vain, to create multiple fixtures in cakePhP. Currently, I need to test a function that requires two different fixture database tables. If possible, could someone please post some simple snippet and show me create multiple fixtures.
Furnace,
have you taken a look at cake's bake utility? You can bake fixtures with it.
cake bake fixture all
bakes all fixtures at once in your app. Use with care in order not to overwrite existing code.
Edit0:
Use
cake bake fixture help
if you have further questions.
Here's a simple fixture: app/tests/fixtures/entity_fixtures.php
In your case you will create two of these files, one per model and with different names.
<?php
class EntityFixture extends CakeTestFixture {
var $name = 'Entity';
var $table = 'entities';
// Define the fields
var $fields = array(
'entity_id' => array('type' => 'integer', 'key' => 'primary'),
'type' => array('type' => 'string' , 'length' => 255),
'created' => 'datetime',
'modified' => 'datetime'
);
var $records = array(
array('entity_id' => 1, 'type' => 'entity', 'created'=>'2010-01-01', 'modified' => '2010-01-01')
);
}
?>
When in your test case include your fixtures at the top of your test case
class EntityTestCase extends CakeTestCase {
var $fixtures = array(
'plugin.myplugin.entity', // Including a sample plugin fixture
'entity', // The fixture above shown in code above
'blogs' // Including a third fixture (should be in app/tests/fixtures/blog_fixture.php)
);
}
Related
I'm trying to display data in cakePHP with a Google Chart.
I downloaded the GoogleCharts plugin on https://github.com/scottharwell/GoogleCharts and put it in my App/Plugin directory. I load all plugins in my application's bootstrap file with
CakePlugin::loadAll();
In my Controller, I put
App::uses('GoogleCharts', 'GoogleCharts.Lib');
and
public $helpers = array('GoogleCharts.GoogleCharts');
, so cakePHP is able to detect I will work with this plugin. Of course, I created the GoogleChartHelper.php in App/View/Helper.
Before working with my data, what I want is just to display an example of chart to see if it is working. Which is not! I copied the example of the above-provided link (on github.com), so here is my Controller class:
<?php
App::uses ( 'AppController', 'Controller');
App::uses ('GoogleCharts', 'GoogleCharts.Lib');
class StatisticsController extends AppController{
public $helpers = array('GoogleCharts.GoogleCharts');
public $components = array (
'Paginator',
'Session'
);
public function index(){
//Setup data for chart
$chart = new GoogleCharts();
$chart->type("LineChart");
//Options array holds all options for Chart API
$chart->options(array('title' => "Recent Scores"));
$chart->columns(array(
//Each column key should correspond to a field in your data array
'event_date' => array(
//Tells the chart what type of data this is
'type' => 'string',
//The chart label for this column
'label' => 'Date'
),
'score' => array(
'type' => 'number',
'label' => 'Score',
//Optional NumberFormat pattern
'format' => '#,###'
)
));
//You can also manually add rows:
$chart->addRow(array('event_date' => '1/1/2012', 'score' => 55));
//Set the chart for your view
$this->set(compact('chart'));
}
}
In my View, I put the code
<div id="chart_div"><?php $this->GoogleChart->createJsChart($chart);?></div>
(without "s" to "GoogleChart" (not like on the download page, where is it written "GoogleCharts"), which took me 3 hours to notice)
My charts should be displayed on the page, but I got the following error:
Warning (512): Method GoogleChartHelper::createJsChart does not exist
[CORE\Cake\View\Helper.php, line 192]
(and if I put the "s" in the View, my page displays like without any error but without any chart...)
Am I missing something?
N.B. : I didn't copy the first method given on the github page, because with it a new worst error appears:
Error: Call to a member function find() on null
That method is:
//Get data from model
//Get the last 10 rounds for score graph
$rounds = $this->Round->find(
'all',
array(
'conditions' => array(
'Round.user_id' => $this->Auth->user('id')
),
'order' => array('Round.event_date' => 'ASC'),
'limit' => 10,
'fields' => array(
'Round.score',
'Round.event_date'
)
)
);
Please help me, I just want to display some random data in a chart and it should not be complicated (but with cakePHP, everything seems complex)...
The problem is that one step was missing:
you have to write
<?php echo $this->fetch('script'); ?>
in View/Layouts/bootstrap.ctp and if you followed all other steps, it should work!
Hello there,
thanks in adv for help.
i have two table: named as options fields are (id,option_title,created,status) and second table as option values fields as (id,option value,options_id,created,status). THe option values table has a foreign key as options_id. Now when i created association between these two table . i didn't work.. Let me explain you how i am creating association.
In the Option model i am using following code.
var $hasMany = array(
'values' => array(
'className' => 'Optionvalue',
'foreignKey' => 'options_id'
));
But this is not working and i am not able to get data from options table. Can any please advice me.. where i am wrong. I just need options table data in the optionsvalue add view file.
Assuming you have a table called options and another called optionvalues. Here is how the Option model looks like
class Option extends AppModel {
public $hasMany = array(
'Optionvalue' => array(
'className' => 'Optionvalue',
'foreignKey' => 'option_id',
'dependent' => FALSE
)
);
}
In the Optionvalue model you then go like this
class Optionvalue extends AppModel {
public $belongsTo = array(
'Option' => array(
'className' => 'Option',
'foreignKey' => 'option_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
}
This is how it should look like. In the Optionvalue Add method, you will need to write this in the view
echo $this->Form->create('Optionvalue');
echo $this->Form->input('option_id');
echo $this->Form->end('Save');
and the options will appear by themselves.
Very important though, you did not follow the naming conventions. options_id needs to be option_id among others.
Use
option_id in place of 'options_id'
Cakephp strongly follows naming conventions.
http://book.cakephp.org/2.0/en/getting-started/cakephp-conventions.html
Also looks like you are not using proper naming conventions for other places too.
I'm using the cakephp media plugin in my project using the monolithic style attachments table, i.e. all the attachments go in the one table with foreign_key, model, group etc. saved with the file details. So my model looks like:
class ProjectProfile extends AppModel {
var $name = 'ProjectProfile';
var $useDbConfig = 'default';
var $useTable = 'project_profiles';
var $actsAs = array('Media.Transfer', 'Media.Generator');
public $belongsTo = array(
'Project' => array(
'className' => 'Project',
'foreignKey' => 'pjID'
)
);
var $hasMany = array(
'Photo' => array(
'className' => 'Media.Attachment',
'order' => 'Photo.basename, Photo.id',
'foreignKey' => 'foreign_key',
'conditions' => array('Photo.model' => 'ProjectProfile', 'Photo.group' => 'Photo'),
'dependent' => true)
);
Then a saveAll in the controller when saving my record saves the attached file.
This all works fine, however I'd really like to be able to upload multiple files at once, which the plugin does support by doing this in the form:
echo $this->Form->hidden('Photo.0.model', array('value' => 'Photo'));
echo $this->Form->input('Photo.0.file', array('type' => 'file');
echo $this->Form->hidden('Photo.1.model', array('value' => 'Photo'));
echo $this->Form->input('Photo.1.file', array('type' => 'file');
echo $this->Form->hidden('Photo.2.model', array('value' => 'Photo'));
echo $this->Form->input('Photo.2.file', array('type' => 'file');
But I think you'd agree that's a bit cumbersome to have to click browse for each individual file. The simplist method I could see to to allow multiple file uploads was to use the HTML5 multiple file section option - http://bakery.cakephp.org/articles/veganista/2012/01/31/html_5_multiple_file_upload_with_cake :
echo $this->Form->input('files.', array('type' => 'file', 'multiple'));
This allows you to shift click in the file browser to select multiple files then puts the files into an array to save... however, this field format isn't handled by the media plugin. Also, there'd be no way to add the model, group etc. fields on the save as far as I could see.
So, does anybody know how I can handle multi file uploads with the media plugin using the monolithic model? I'm open to all suggestions.
Thanks in advance.
Will this CakePHP 2.x plugin - AjaxMultiUpload - work for you? I think that does exactly what you need it to.
I am using CakePHP 1.3.
I have a few questions regarding CakePHP Models:
1) Is there a way to define a Model with conditions, such that when invoked using the Containable, behavior, I do not need to define 'conditions' for it again. For example: I have two models - "Store" and "Deal" where "Store" that hasMany "Deal". I want to accomplish the following without having to define these conditions for "Deal" every time:
$this->Store('all', array('contain'=>array('Deal'=>array('isactive'=>1,'now() < expirydate', 'qty > 0')));
2) Also, is there a way to define relationships between Models differently based on conditions? In other words, how can I define "Store" hasMany "Deals", "ActiveDeal", "ExpiredDeal", etc.., all on the 'deals' table but differing based on conditions I set for each.
Much appreciate any help.
Thanks/Regards..
If you look at the first couple of code examples on the Associations: Linking Models Together page of the CakePHP Cookbook, you'll see that you can add conditions to your model joins that will work whenever you do a basic find.
Therefore you should be able to do something like the following:
class Store extends AppModel {
var $name = 'Store';
var $hasMany = array(
'Deal' => array(
'className' => 'Deal',
'foreignKey' => 'store_id',
'conditions' => array(
'Deal.isactive' => '1',
'now() < Deal.expirydate',
'Deal.qty > 0'
),
'order' => ''
),
'ExpiredDeal' => array(
'className' => 'Deal',
'foreignKey' => 'store_id',
'conditions' => array('now() >= ExpiredDeal.expirydate'),
'order' => ''
)
);
}
My business directory application calls for 3 chained select boxes, and I'm using cakephp to build this application.
The hierarchy and order of choices for the sections is this:
1 - business group
2 - business type
3 - city (included in table customer)
The relationships are:
customer HABTM business types
business groups have many business types
business types have one business group, HABTM customers
I have searched for jquery plugins that help with this, and found one by Remy Sharp, but it doesn't have the more complex relationships I have.
http://remysharp.com/2007/09/18/auto-populate-multiple-select-boxes/
What I imagine happening is the first selection box (business groups) is pre-populated and once a selection is made, an event listener send a message that filters the second selection box, and the same for the third.
What I don't know is how to structure the search action based on the event listener.
Any advice or am I way off base?
As always, I come to the well for help.
Much appreciated.
Paul
Thanks very much Nick, I've read many of your posts I really appreciate your response.
I've followed your instructions but have run into problems. I've tried my best to resolve them but haven't figured it out.
This is what I've done so far:
1) created 'chained' actions in both the business_type and business_directory (renamed customer to business directory, which is more appropriate.)
business type chained action:
function chained($business_group_id) {
$business_types = $this->BusinessType->find('list', array(
'conditions' => array( 'BusinessType.business_group_id' => $business_group_id)
));
$this->set('business_types', $business_types);
}
business directory chained action:
function chained($business_type_id) {
$business_directories = $this->BusinessDirectory->bindModel(array( 'hasOne' => array('business_directories_business_types' )));
$business_directories = $this->BusinessDirectory->find('all', array(
'fields' => array( ' BusinessDirectory.city'),
'conditions' => array( 'business_directories_business_types.business_type_id' => $business_type_id)
));
$this->set('business_directories', $business_directories);
}
I did find that with a HABTM relationship, using find 'list' didn't create the join query, whereas find 'all' did.
2) I then created a search action in the business directory and corresponding view.
For the business groups I created a getList action to populate the option list in the search form:
function getList() {
return $this->BusinessGroup->find('list');
}
In the search view, I've added the javascript for the chain select:
<script type="text/javascript">
<!--
$(function () {
var group = $('#businessGoup');
var type = $('#businessType');
var city = $('#businessDirectoryCity');
type.selectChain({
target: city,
url: '../business_directories/chained/'+$(this).val(),
data: { ajax: true, anotherval: "anotherAction" }
});
group.selectChain({
target: type,
url: '../business_types/chained/'+$(this).val()
}).trigger('change');
});
//-->
</script>
And the form:
create('business_directories', array('action'=>'/search_results')); ?>
input('business_group_id',
array( 'type' => 'select',
'id' => 'businessGoup',
'empty' => '-- Select Business Group --',
'multiple' => true,
'options' => $this->requestAction('/business_groups/getList' ),
'label' => 'Business Group'));
?>
input('business_type.id',
array( 'type' => 'select',
'id' => 'businessType',
'empty' => '-- Select Business Type --',
'multiple' => true,
'options' => 'none selected',
'label' => 'Business Type'));
?>
input('business_directories.id',
array( 'type' => 'select',
'id' => 'businessDirectoryCity',
'empty' => '-- Select City --',
'multiple' => true,
'options' => 'options',
'label' => 'City'));
?>
end('Search'); ?>
When I test the business type chain function, /business_types/chained/1, everything works.
But when I test the search view, I get a javascript alert error. Then when I check firebug, I get the following two errors:
Warning (2): Missing argument 1 for BusinessTypesController::chained() [APP\controllers\business_types_controller.php, line 71]
Notice (8): Undefined variable: business_group_id [APP\controllers\business_types_controller.php, line 73]
Any additional help with this is very much appreciated.
Thanks, Paul
What you need is to have 2 actions in the controllers (business_type and customer).
each action should look like this. In that case for the business type
function chained($parent_id){
$business_types = $this->BusinessType->find('list', array('conditions'=>'BusinessType.business_group_id'=>$parent_id));
$this->set('business_types', $business_types);
}
of course you need also view for that action which will format the values in the proper format for the chained select.
For Business group you need to show all values directly so no ajax is needed.
The Customer controller's action is similar, but you need to select cities of all related customers.
Then with the chained select you need to set the proper elements and set the proper actions which need to be called.
i.e.:
$('#id-of-the-business-group').selectChain({
target: $('#id-of-the-business-type-field'),
url: '/business_types/chained/'+$(this).val()
});