php mvc change default url pattern - php

I'm using yaf php framework
I want to get param array.
ex:
My url:... mvcSample/svc/saveUser/user1/pass/a#b.c/joe/foo
My output params dump:
array (size=3)
'user1' => string 'pass' (length=4)
'a#b.c' => string 'joe' (length=3)
'foo' => null
I want:
array (size=5)
1 =>string 'user1'
2 => string 'pass'
3 => string 'a#b.c'
4 => string 'joe'
5 =>string 'foo'
How to change default url pattern ?
Thank you

Since Yaf is very well undocumented, the only option I can think about is to parse URI by Your own:
$parts = explode('/', $this->getRequest()->getRequestUri());
But You will get garbage on begining of $parts array.
Propably, sooner or later You will start to trying custom URL routing (some samples You can find here: http://docs.php.net/manual/da/yaf-route-regex.construct.php), which will allow You to parse URLs using regexps and pass matched groups to controller:
/* in Bootstrap.php */
$dispatcher->getRouter()->addRoute('saveUser',
new Yaf_Route_Regex(
',^/mvcSample/svc/saveUser/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)$,',
array(
'controller' => 'svc',
'action' => 'saveUser',
),
array(
1 => 'username',
2 => 'password',
3 => 'email',
4 => 'firstname',
5 => 'somefooshmoo',
),
)
);

Related

Getting param value in lower case only - PHP phalcon

I am passing some params in url as below:
sample/team/highestScore/1
My router code for accepting this URL is:
$this->add('/sample/team/{tab:[a-zA-Z0-9-_]+}/{matchType:[0-9]+}',array('action' => 'teamAction'))->setName('sample');
But in controller I am getting the value of param 'tab' as highestscore, means in lowercase. I need the param value as highestScore. How can I get the value without case conversion.
Please advise. Thanks in advance.
Controller: (app/controllers/someController.php)
function teamAction($tab = null, $matchType = null)
{
exit(var_dump([
$tab,
$matchType
]));
}
route ( app/config/router.php )
$router = $di->getRouter();
$router->add(
'/sample/team/{tab:[a-zA-Z0-9-_]+}/{matchType:[0-9]+}',
[
'controller' => 'some',
'action' => 'team'
]
);
$router->handle();
testing url phalcon_path/sample/team/highestScore/1
array (size=2)
0 => string 'highestScore' (length=12)
1 => string '1' (length=1)

Zend route with unlimited parameters

I am using Zend 1.10. I am trying to create a route for unlimited variables like abc.com/var1/var2/var3 and so on.
Till now i have searched and find out that i can add route for each variable like
$route = new Zend_Controller_Router_Route(
'/emaillog/:var1',
array(
'controller' => 'emaillog', // The controller to point to.
'action' => 'index', // The action to point to, in said Controller.
':var1' =>null //default value if param is not passed
)
);
$frontController->getRouter()->addRoute('emaillogWithVar1', $route);
and for second variable,
$route = new Zend_Controller_Router_Route(
'/emaillog/:var1/:var2',
array(
'controller' => 'emaillog', // The controller to point to.
'action' => 'index', // The action to point to, in said Controller.
':var1' =>null, //default value if param is not passed
':var2' =>null //default value if param is not passed
)
);
$frontController->getRouter()->addRoute('emaillogWithVar2', $route);
But the work i going to do, can contain 1-∞ infinite variables.
So i want to have once route for unlimited variables.
Any help will be appreciated!
There is a way to get infinite params. For that you don't have to declare them.
Lest say the url is index/test/p1/p2/p3/p4/p5, now if you try the following inside IndexController:
public function testAction()
{
var_dump($this->getRequest());
}
You will get a dump of an instance of Zend_Controller_Request_Http, in that dump, you will see, 2 properties, _params & _pathInfo, Like:
protected '_pathInfo' => string '/index/test/p1/p2/p3/p4/p5' (length=26)
protected '_params' =>
array (size=5)
'controller' => string 'index' (length=5)
'action' => string 'test' (length=4)
'p1' => string 'p2' (length=2)
'p3' => string 'p4' (length=2)
'module' => string 'default' (length=7)
1st method: Now in _params, they will occur as key => value pairs, as long as they are even, the last odd param will be ignored. You can get these by(for example):
$params = $this->getRequest()->getParams();
unset($params['controller']);
unset($params['action']);
unset($params['module']);
$params = array_merge(array_keys($params), array_values($params));
var_dump($params);
Output:
array (size=4)
0 => string 'p1' (length=2)
1 => string 'p3' (length=2)
2 => string 'p2' (length=2)
3 => string 'p4' (length=2)
2nd Method: OR you can use _pathinfo to get the params using explode, like:
$path = $this->getRequest()->getPathinfo();
$params = explode('/', $path);
unset($params[0]);
unset($params[1]);
unset($params[2]);
var_dump($params);
Output:
array (size=5)
3 => string 'p1' (length=2)
4 => string 'p2' (length=2)
5 => string 'p3' (length=2)
6 => string 'p4' (length=2)
7 => string 'p5' (length=2)

CakePHP- saving associated model data

I have two models .. One is called Schedule and the other ScheduleContact.
Schedule belongsTo ScheduleContact
From an action belonging to scheduleController, I want to save values coming from a serialized form for the main model as well as the associated model.
In my view I have the following
<?php echo $this->Form->input('Schedule.start_at', array('id' => 'start_at', 'type' => 'hidden')); ?>
<?php echo $this->Form->input('Schedule.finish_at', array('id' => 'finish_at', 'type' => 'hidden')); ?>
<?php echo $this->Form->input('ScheduleContact.0.name', array('id' => 'name','div' => 'inline-input')); ?>
<?php echo $this->Form->input('ScheduleContact.0.surname', array('id' => 'surname','div' => 'inline-input compact')); ?>
etc..
The request data comes in this form (from var_dump($this->request->data)):
array (size=3)
'Schedule' =>
array (size=3)
'start_at' => string '2014-3-25 11:15' (length=15)
'finish_at' => string '2014-03-25 11:30:00' (length=19)
'donation_method_id' => string '1' (length=1)
'ScheduleContact' =>
array (size=1)
0 =>
array (size=6)
'name' => string 'Jane' (length=4)
'surname' => string 'Powell' (length=6)
'address' => string 'Hamilton Hodell, 5th Floor 66-68 Margaret Street' length=39)
'city' => string 'London' (length=6)
'tel_no' => string '+44(0)20-7636 1221' (length=18)
'email' => string 'powell_jane#gmail.com' (length=22)
'log' =>
array (size=3)
'ds' => string 'default' (length=7)
'sql' => string 'SELECT `Schedule`.`id`, `Schedule`.`donation_method_id`, `Schedule`.`schedule_contact_id`, `Schedule`.`start_at`, `Schedule`.`finish_at`, `DonationMethod`.`id`, `DonationMethod`.`donation_method`, `DonationMethod`.`recovery_time`, `DonationMethod`.`duration`, `ScheduleContact`.`id`, `ScheduleContact`.`name`, `ScheduleContact`.`surname`, `ScheduleContact`.`address`, `ScheduleContact`.`city`, `ScheduleContact`.`tel_no`, `ScheduleContact`.`email`, `ScheduleContact`.`donor_id` FROM `blood_services_db`.`schedule'... (length=852)
'hash' => string '5f2b2b3a462f6555cb5290fb49c42df04a7948e0' (length=40)
Finally I am trying to save the data like so :
if($this->Schedule->saveAssociated($this->request->data)){
which is not saving anything to the database, therefore the this if condition is never met.
What could be wrong ? Thanks
Basically the problem was that saveAssociated needs to be applied in the main model. With that in mind, as it was set up above, the main model had a bolongsTo relationship, which means that the current model contains the foreign key., which is also indeed correct. So where is the problem you might ask?
The problem is that saveAsocciated is equivalent to
$user = $this->User->save($this->request->data);
// If the user was saved, Now we add this information to the data
// and save the Profile.
if (!empty($user)) {
// The ID of the newly created user has been set
// as $this->User->id.
$this->request->data['Profile']['user_id'] = $this->User->id;
}
Which means that it attempts to save the main model first. Therefore my setup was incorrect since the main model needed to be ScheduleContact, since the foreign key will be saved inside the Schedule model after data in ScheduleContact id successfully inserted.
There you go... CakePHP is Great once you get past that learning curve.
Your Model-Name is breaking Cake's naming convention. It should be:
ScheduleContact
A few questions to give you a better answer:
Can you add the Model Association Variables ($belongsTo, etc)?
Do you use Containable behaviour?

Optimizing query with large result set

I have a CakePHP model, let's call it Thing which has an associated model called ItemView. ItemView represents one page view of the Thing item. I want to display how many times Thing has been viewed, so I do the following in my view:
<?php echo count($thing['ItemView']); ?>
This works, however as time goes on the result set of this query is going to get huge, as it's currently being returned like so:
array(
'Thing' => array(
'id' => '1',
'thing' => 'something'
),
'ItemView' => array(
(int) 0 => array(
'id' => '1',
'thing_id' => 1,
'created' => '2013-09-21 19:25:39',
'ip_address' => '127.0.0.1'
),
(int) 1 => array(
'id' => '1',
'thing_id' => 1,
'created' => '2013-09-21 19:25:41',
'ip_address' => '127.0.0.1'
),
// etc...
)
)
How can I adapt the model find() to retrieve something like so:
array(
'Thing' => array(
'id' => '1',
'thing' => 'something',
'views' => 2
)
)
without loading the entire ItemView relation into memory?
Thanks!
So it's pretty straight forward, we can make use of countercache - Cake does the counting for you whenever a record is added into/deleted fromItemView:
Nothing to change in your Thing.php model
Add a new INT column views in your things table.
In your ItemView.php model, add counterCache like this:
public $belongsTo = array(
'Thing' => array(
'counterCache' => 'views'
)
);
Then next time when you do addition/deletion via ItemView, Cake will automatically recalculate the counting and cache into views for you, so the next time when you do the query, you also need to make sure you specify recursive = -1 as what #Paco Car has suggested in his answer:
$this->Thing->recursive = -1;
$this->Thing->find(...); //this will returns array of Thing + the field "views"
// --- OR ---
$this->Thing->find(array(
'conditions' => array(
//... your usual conditions here
),
//... fields, order... etc
//this will make sure the recursive applies to this call, once only.
'recursive' => -1
);

How to check if filters have been applyed in template?

I'm working on an admin-generator module. I'd like to hide the item-list until the user has used the filters. So I'd like to check, if the filter-form has been sent.
Is there any var I can check for this in the indexSuccess.php Template?
Filters are stored inside the session when the user submit them.
So, in your template, you can access defined filter by calling the session. If you don't have defaults filter, it will return an empty array (might be sfOutputEscaperArrayDecorator if you use output protection).
If you module name is car for example, you can get filters inside your template using:
$filters = $sf_user->getAttribute('car.filters', null, 'admin_module');
And if you use output protection, you can do:
$filters = sfOutputEscaper::unescape($sf_user->getAttribute('car.filters', null, 'admin_module'));
If you do not have filters, you will get something like this with a var_dump (with the first solution):
object(sfOutputEscaperArrayDecorator)[181]
private 'count' => int 0
protected 'value' =>
array
empty
protected 'escapingMethod' => string 'esc_specialchars' (length=16)
And with the second:
array
empty
For example, if you have some filters define, you will get :
array
'model' =>
array
'text' => string 'test' (length=4)
'updated_at' =>
array
'from' => null
'to' => null
'created_at' =>
array
'from' => null
'to' => null

Categories