In Typo3 I have my custom content elements (CEs) defined like so, for example:
CREATE TABLE tt_content
(
my_rich_text_relation int(11) unsigned DEFAULT '0',
);
# Custom CE for displaying rich text.
CREATE TABLE tx_mythemes_rich_text
(
uid int(11) NOT NULL auto_increment,
pid int(11) DEFAULT '0' NOT NULL,
text text,
....
);
And:
lib.myContentElement = FLUIDTEMPLATE
lib.myContentElement {
templateRootPaths.0 = EXT:my_themes/Resources/Private/Templates/ContentElements/
partialRootPaths.0 = EXT:my_themes/Resources/Private/Partials/ContentElements/
layoutRootPaths.0 = EXT:my_themes/Resources/Private/Layouts/ContentElements/
}
tt_content {
my_rich_text >
my_rich_text =< lib.myContentElement
my_rich_text {
templateName = RichText
dataProcessing {
330 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
330 {
table = tx_mythemes_rich_text
pidInList = this
where = uid=
where.dataWrap = |{field:mythemes_rich_text_relation}
as = richText
}
}
}
This works in my local system (Docker image) but I don't know why in our beta platform (where the context is not "development" it doesn't. When I add a new custom CE and refresh the caches, it gets displayed, but as soon as something changes (e.g. I add a new CE to the page), the Template of the CE doesn't get rendered (funny thing: the Layout does get rendered).
What can be happening? This looks so much like a cache problem.
Thanks in advance!
Related
As CodeIgniter comes out of the box, it supportes one controller for each unique url.
So, let's say i have the following urls in my routes.php file:
$route['default_controller'] = "homepage";
$route['404_override'] = "homepage/not_found";
$route['^products$'] = "product/list";
$route['^product/(:any)$'] = "product/details";
My urls will look like this:
product list => http://www.mywebsite.com/products
product details => http://www.mywebsite.com/product/my-custom-product
In the controller where I build the products list, I create the url for each product like this:
$this->db->from('products');
$products_result = $this->db->get();
$data['products'] = array();
foreach ($products_result->result() as $row)
{
$data['products'][] = array(
'title' => $row->title,
'image' => $row->image,
'url' => site_url('product/' . $row->url)
);
}
$this->load->view('products/list_view', $data);
But there is too much redundancy for each url. I have to write the url every time I want to echo it somewhere. If I want to change the url, I have to open each php file and replace them all.
Question: Isn't there a "method" I can use to call the controller name and its method and that "method" returns the url for that one? Something like this:
build_site_url('product/details', array('my-product-url'));
where the first argument is the controller and its method (since only one controller exists for a url pattern), and the second argument is the array of url parts.
What you're looking for is a feature called reverse routing. There is no such feature built into CodeIgniter at this time, and any library I could find was done in like 2010, so probably not the most up-to-date.
However, there are articles and pull requests out there relating to reverse routing, so if you are experienced enough, you should be able to put something together for your application.
Otherwise, your best bet may be to create helpers for your most common URLs (like your products). So you could do something like echo product_url('my-product-name');, and you would only need to adjust the URL in the helper function.
I am not sure what exactly that you desired, but you can override controller behaviour using _remap() function;
look: http://ellislab.com/codeigniter/user-guide/general/controllers.html#remapping
e.g.
public function _remap($method){
if ($method == 'product/details') {
///do what you want to do
}
You could either use a default lookup function in the product controller (described in the CI Routing docs; look at the examples).
$route['product/(:any)'] = "catalog/product_lookup";
A URL with "product" as the first segment, and anything in the second
will be remapped to the "catalog" class and the "product_lookup"
method.
Or you could use database driven routes.
Add the table product_slugs to your MySQL database:
CREATE TABLE IF NOT EXISTS `product_slugs` (
`id` bigint(20) NOT NULL auto_increment,
`slug` varchar(192) collate utf8_unicode_ci NOT NULL
PRIMARY KEY (`id`),
KEY `slug` (`slug`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1;
Replace the code in application/config/routes.php with the one below:
$route[ 'default_controller' ] = 'main';
$route[ '404_override' ] = 'error404';
require_once( BASEPATH .'database/DB'. EXT );
$db =& DB();
$query = $db->get( 'product_slugs' );
$result = $query->result();
foreach( $result as $row )
{
$route[ $row->slug ] = 'product/detail/$1;
}
All you would have to do then is to create a record when you create a product entry and you're done:
INSERT INTO `product_slugs` (`slug`) VALUES ('name-of-the-product');
Submitting the data only reloads the page, no errors or messages is given by CakePHP.
The code follows the same/similar structure as the blog tutorial.
The view code
<?php
echo $this->Form->create('Sm');
echo $this->Form->input('recievers', array('rows' => '1'));
echo $this->Form->input('subject');
echo $this->Form->input('message');
echo $this->Form->end('SEND');
?>
Controller code
public function send() {
if ($this->request->is('sm')) {
$this->Sm->create();
if ($this->Sm->save($this->request->data)) {
$this->Session->setFlash('Sms has been added to the database');
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('Unable to send sms.');
}
}
}
Model code
class Sm extends AppModel {
public $validate = array(
'subject' => array(
'rule' => 'notEmpty'
),
'message' => array(
'rule' => 'notEmpty'
),
'recievers' => array(
'rule' => 'notEmpty'
)
); }
Exported SQL
CREATE TABLE IF NOT EXISTS `sms` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`subject` varchar(150) DEFAULT NULL,
`message` text,
`sender` varchar(50) DEFAULT NULL,
`recievers` text,
`sent` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
You've specified an incorrect request 'method';
if ($this->request->is('sm')) {
Should be:
if ($this->request->is('post')) {
I suspect you got confused by the examples on CakePHP, which use a 'post' Model. However this line is to check the type of request used to access the page, e.g. post, get, put.
By checking for the right request method, CakePHP will only insert/update the data is the form is sent/submitted, otherwise the form is just shown without updating the database
You forget to define name property inside model.
var $name = 'Sm';
Just a few minutes ago, I was facing same type of problem. My problem was more weird. In my controller I used something like this:
if( $this->MyModel->save( $this->request->data ) ) {
//positive. proceed.....
}
else {
//negative. show error
pr( $this->MyModel->validationErrors );
}
As you can see I've handled the negative case but still I could see nothing. Even in my model, I used beforeSave and afterSave to check. In my beforeSave model, I could see a perfectly formatted array ready to be saved but I afterSave was not triggering which means the data was not saved. Hence I should see error from my controller. Still no solution.
Now this is how I figured out the problem. I checked the table the data is gonna be saved into. The table had lots of columns with NOT NULL attribute. The data I was saving had some fields with NULL values. So theoretically, I should see validationErrors in the controller as a reason but unfortunately it was not showing. Setting those fields nullable solved my problem. So my suggestion to you is to check which fields might have NULL value and set those nullable and make sure the NOT NULL fields have some values.
Hope this helps. Cheers!!!
This is my complete Wordpress plugin file:
<?php
function wp_create_table_install()
{
global $wpdb;
$table_name = $wpdb->prefix.'createtable';
$sql = 'CREATE TABLE '.$table_name.'(
id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(75)
);';
require_once(ABSPATH.'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
function wp_create_table_insert_data()
{
global $wpdb;
$table_name = $wpdb->prefix.'createtable';
$id = 1;
$name = 'WP Create Table!';
$wpdb->insert($table_name, array('id' => $id, 'name' => $name));
}
register_activation_hook(__FILE__, 'wp_create_table_install');
register_activation_hook(__FILE__, 'wp_create_table_insert_data');
?>
When I activate the plugin, it always tries to create a table and insert data. How could I do it once, just in the first plugin activation?
Thank you.
A quicker way would be to add [IF NOT EXISTS] in your CREATE statement so that you don't get an error if your table already exists.
Before running CREATE TABLE, you could query information_schema.tables to check to see whether or not the table already exists.
Unfortunately, there's no way to run something on "install" - surprisingly, WordPress doesn't provide any hooks for install as opposed to activation!
The way people cope with this is to set and test an option - if the option is not set, then create the tables, and if it is set do nothing or do a DB upgrade. Options are read in and cached so there is no performance penalty to doing this.
$opt = get_option(MYPLUGIN_OPTIONS);
$opt['dbversion'] = 100;
...
update_option(MYPLUGIN_OPTIONS, $opt);
How can I upload a file using cakephp? is there any framework support for file uploading or should I write my own code for this ?
Edit (2015): Please see the Awesome CakePHP list for current file plugins (2.x branch here)
Original answer:
CakePHP upload plugins in active development (as of Oct 2010):
David Persson's Media Plugin [slides]
WebTechNick's CakePHP File Upload Handling Plugin [blog post]
Miles Johnson's Uploader Plugin [website]
Meio Código's MeioUpload 2.0 Behavior Plugin [website]
You could also use the File class, but I wouldn't reinvent the wheel on this one.
both is possible
for beginners this is probably the better choice:
http://www.milesj.me/resources/script/uploader-plugin
This component could help you out: http://cakeforge.org/snippet/detail.php?type=snippet&id=36.
Allows uploads to either a database or a directory using FTP. I have some experience with CakePHP, however I have not yet tried this component.
To just get going try this.
I spent two days searching for a simple way to upload files, I tried lots of methods and couldn't get any to work. This works. It is not secure, it is super basic. For me it is now a springboard. I would use this to understand the processes. Then you can build it up in complexity.
For me I struggled with trying to save $this->data - but of cause it is not like the cakePHP blog tutorial. The data you want (all the file info) is buried a couple of levels down in nested arrays so $this->data['Doc']['files'] is what you are after.
SQL
CREATE TABLE IF NOT EXISTS `docs` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(300) NOT NULL,
`type` varchar(300) NOT NULL,
`tmp_name` varchar(300) NOT NULL,
`error` tinyint(1) NOT NULL,
`size` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ;
MODEL
<?php
class Doc extends AppModel {
}
?>
VIEW
<h1>Uploads</h1>
<table>
<tr>
<th>ID</th><th>File Name</th><th>Size</th>
</tr>
<?php foreach($files as $file): ?>
<tr>
<td><?php echo $file['Doc']['id'];?></td>
<td><?php echo $this->Html->link($file['Doc']['name'],array('controller' => 'files','action'=>'uploads',$file['Doc']['name']));?></td>
<td><?php echo number_format($file['Doc']['size']/1023,0).' KB';?></td>
</tr>
<?php endforeach;?>
</table>
<h1>Add a File</h1>
<?php
echo $this->Form->create('Doc',array('type'=>'file'));
echo $this->Form->file('File');
echo $this->Form->submit('Upload');
echo $this->Form->end();
?>
CONTROLLER
<?php
class DocsController extends AppController
{
public $helpers = array('Html','Form','Session');
public function index()
{
// -- list the files -- //
$this->set('files',$this->Doc->find('all'));
// -- Check for error -> Upload file to folder -> Add line to database -- //
if($this->request->is('post'))
{
if($this->data['Doc']['File']['error']=='0')
{
if(file_exists('files/uploads/' . $this->data['Doc']['File']['name']))
{
$this->Session->setFlash('A file called ' .$this->data['Doc']['File']['name']. ' already exists');
} else {
move_uploaded_file($this->data['Doc']['File']['tmp_name'], 'files/uploads/' . $this->data['Doc']['File']['name']);
}
$this->Doc->save($this->data['Doc']['File']);
$this->redirect(array('action'=>'index'));
}
}
}
}
?>
I did
yiic shell "/path/to/my/app"
model *
crud users
I cannot add or update users. I can list them, and delete them. Also I thought I was supposed to see the primary keys.
CREATE TABLE IF NOT EXISTS `users` (
`user_id` int(11) NOT NULL auto_increment,
`user_username` varchar(25) collate latin1_general_ci NOT NULL,
`user_username_clean` varchar(25) collate latin1_general_ci NOT NULL,
`user_password` varchar(64) collate latin1_general_ci NOT NULL,
`user_register_time` int(11) NOT NULL,
`user_code` varchar(15) collate latin1_general_ci NOT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB;
Probable reason could be DB username/password which you have provided in config/main.php doesn't have access to modify database. Just making a guess, post more details about the issue to better understand it.
It looks like the suggestion about database permissions above was the answer, but just a friendly note: the newer versions of Yii have a new visual (GUI) CRUD generator called "Gii". Check out the instructions here, it's much nicer than yiic and may solve some problems creating CRUD code:
http://www.yiiframework.com/doc/guide/quickstart.first-app#generating-crud-code
The problem is while generating function loadModel in appController.php
The generator creates the function loadModel like this:
public function loadModel($id)
{
$model=App::model()->findByPk((int)$id); // <- Error Line
if($model===null)
throw new CHttpException(404,'The requested page does not exist.');
return $model;
}
And the correct loadModel function is as follows:
public function loadModel($id)
{
$model=App::model()->findByPk($id); // <- Fixed Line
if($model===null)
throw new CHttpException(404,'The requested page does not exist.');
return $model;
}
I hope to have helped better understand the problem and correct them in the package without touching the Original of the generator, as it should appear in YII updates own correction.
Patch to enable non-integer primary keys
--- yii-1.1.5.r2654/framework/cli/views/webapp/protected/config/main.php 2010-11-14 20:35:42.000000000 +0000
+++ yii-1.1.5.r2654/framework/cli/views/webapp/protected/config/main.php 2010-12-09 16:59:01.783001000 +0000
## -42,4 +42,5 ##
'/'=>'/view',
'//'=>'/',
+ '//'=>'/',
'/'=>'/',
),
--- yii-1.1.5.r2654/framework/gii/generators/crud/templates/default/controller.php 2010-11-14 20:35:45.000000000 +0000
+++ yii-1.1.5.r2654/framework/gii/generators/crud/templates/default/controller.php 2010-12-09 16:47:54.053001002 +0000
## -163,5 +163,5 ##
public function loadModel($id)
{
- $model=modelClass; ?>::model()->findByPk((int)$id);
+ $model=modelClass; ?>::model()->findByPk($id);
if($model===null)
throw new CHttpException(404,'The requested page does not exist.');
--- yii-1.1.5.r2654/framework/gii/GiiModule.php 2010-11-14 20:35:45.000000000 +0000
+++ yii-1.1.5.r2654/framework/gii/GiiModule.php 2010-12-09 16:49:22.183001002 +0000
## -53,4 +53,5 ##
* 'gii/'=>'gii/',
* 'gii//'=>'gii//',
+ * '//'=>'/',
* ...other rules...
* ),