I want to customize my url in cakephp
http://localhost/cantq4tickets/events/event_detail/1
instead of 1 (event_id) in url i want event name ex. birthday party.
In your events db table add field 'slug' VARCHAR (255)
In your Event model add before save method:
public function beforeSave($options = array()) {
parent::beforeSave();
$name_to_slug = Inflector::slug($this->data['Event']['name'], $replacement = '-');
$this->data['Event']['slug'] = strtolower($name_to_slug);
return true;
}
In your router
Router::connect('/events/*', array('controller' => 'events', 'action' => 'details'));
links in your views:
<?php echo $this->Html->link($event['Event']['name'],array('controller'=>'events','action'=>'details',$event['Event']['slug'])); ?>
in your EventsController::details($slug=null) findBySlug
You are after Routing which gives you some flexibility in making the URLs pretty. I'd suggest reading the Cookbook first and then perhaps going over some of these examples: http://lecterror.com/articles/view/advanced-routing-with-cakephp-one-example
Related
ZF2 docs show the following example in terms of using Db\RecordExists validator with multiple columns.
$email = 'user#example.com';
$clause = $dbAdapter->quoteIdentifier('email') . ' = ' . $dbAdapter->quoteValue($email);
$validator = new Zend\Validator\Db\RecordExists(
array(
'table' => 'users',
'field' => 'username',
'adapter' => $dbAdapter,
'exclude' => $clause
)
);
if ($validator->isValid($username)) {
// username appears to be valid
} else {
// username is invalid; print the reason
$messages = $validator->getMessages();
foreach ($messages as $message) {
echo "$message\n";
}
}
I’ve tried this using my own Select object containing a more complex where condition. However, isValid() must be called with a value parameter.
In the example above $username is passed to isValid(). But there seems to be no according field definition.
I tried calling isValid() with an empty string, but this does not produce the desired result, since Zend\Validator\Db\AbstractDb::query() always adds the value to the statement:
$parameters = $statement->getParameterContainer();
$parameters['where1'] = $value;
If I remove the seconds line above, my validator produces the expected results.
Can someone elaborate on how to use RecordExists with the where conditions in my custom Select object? And only those?
The best way to do this is probably by making your own validator that extends one of Zend Framework's, because it doesn't seem like the (No)RecordExists classes were meant to handle multiple fields (I'd be happy to be proven wrong, because it'd be easier if they did).
Since, as you discovered, $parameters['where1'] is overridden with $value, you can deal with this by making sure $value represents what the value of the first where should be. In the case of using a custom $select, $value will replace the value in the first where clause.
Here's a hacky example of using RecordExists with a custom select and multiple where conditions:
$select = new Select();
$select->from('some_table')
->where->equalTo('first_field', 'value1') // this gets overridden
->and->equalTo('second_field', 'value2')
;
$validator = new RecordExists($select);
$validator->setAdapter($someAdapter);
// this overrides value1, but since isValid requires a string,
// the redundantly supplied value allows it to work as expected
$validator->isValid('value1');
The above produces the following query:
SELECT `some_table`.* FROM `some_table` WHERE `first_field` = 'value1' AND `second_field` = 'value2'
...which results in isValid returning true if there was a result.
I was wondering if you had any thoughts about this issue: We want to add one more status at a specific 'place' between two statuses, but we ran out of enumeration for it.
The enumeration looks like this:
$s_status_enum_string = "10:new,20:feedback,40:confirmed,50:assigned,52:in progress,53:code review pending,54:merge pending, 56:merged, 58:resolved, 60:testing, 70:tested, 90:closed, 91:updating test documentation";
And I want to add a new status between 52 and 53 so that, on the pull-down menu for status, they appear in the desired order.
I tried different things - including changing the .php file definitions then updating the MySQL table's status field in mantis_bug_table, but it messes up all the views and filters.
Any ideas?
The following steps might help you:
Redefine the enumeration string as per your requirements
Prepare a traceability with your current enumeration values
Update the status field in bugs table with the new values
Add the enumeration in config.php
You may have to reset your previous filters. The filter criteria is stored as a serialized string and it's very difficult to modify.
If anyone is having issues with this you need to change the following:
In config_inc.php modify $g_status_enum_string to ennumerate the new statuses as you see fit.
In custom_constants_inc.php make sure to do the same as above.
In the database, run SQL commands such as this:
UPDATE mantisclone.mantis_bug_table SET status=100 WHERE status=10;
to change the actual records for existing status IDs to new ones.
In custom_strings_inc.php modify $s_status_enum_string and input your new statuses. For example one of mine was:
$s_sanity_test_bug_title = "Set Issue Sanity Test";
$s_sanity_test_bug_button = "Issue Sanity Test Pending";
$s_email_notification_title_for_sanity_test = "The following issue is NOW SANITY TEST PENDING";
Finally you'll need a small script to change the existing ennumerated values in mantis_filters_table. This was mine, alter it as you see fit:
<?php
$mantisDB="myMantisDatabaseName";
mysql_connect("localhost", "XXXX", "YYYY") or die("Could not connect: " . mysql_error());
mysql_select_db($mantisDB);
$result = mysql_query("SELECT id, filter_string FROM $mantisDB.mantis_filters_table");
function parseRecord($statusArray)
{
$newStatus = array( "10" => "100",
"20" => "200",
"50" => "300",
"52" => "400",
"53" => "500",
"54" => "540",
"56" => "560",
"58" => "580",
"60" => "600",
"70" => "700",
"75" => "450",
"90" => "900",
"91" => "910"
);
foreach ($statusArray as $key=>$value)
{
if(array_key_exists($value, $newStatus))
{
echo "Found value $value, replacing it with " . $newStatus[$value] . "\n";
$statusArray[$key] = (int)$newStatus[$value];
}
}
}
while ($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
$statusID = $row["id"];
$serializedString = $row["filter_string"];
$unserializedArray = unserialize(substr($serializedString,3)); // There's a prepended 'v8#' string in there, don't know why.
parseRecord(&$unserializedArray["hide_status"]);
parseRecord(&$unserializedArray["show_status"]);
$newSerialized = "v8#".serialize($unserializedArray);
// echo $newSerialized;
$changeStatus = mysql_query("UPDATE $mantisDB.mantis_filters_table SET filter_string='$newSerialized' WHERE id=$statusID");
}
mysql_free_result($result);
?>
I hope this works, let me know if you're having any issues.
I have a problem with ZF2 RecordExists method. I will explain my problematic case/scenario.
Table: users
Columns: id, emailaddress, websitename
Sample Records:
1, user1#email.com, 1site.com
2, user2#email.com, 1site.com
3, user3#email.com, 2site.com
4, user4#email.com, 2site.com
5, user5#email.com, 1site.com
6, user6#email.com, 3site.com
7, user7#email.com, 4site.com
I am using the following snippet for already exist condition.
//Check that the email address exists in the database
$validator = new Zend\Validator\Db\RecordExists(
array(
'table' => 'users',
'field' => 'emailaddress'
)
);
if ($validator->isValid($emailaddress)) {
// email address appears to be valid
} else {
// email address is invalid; print the reasons
foreach ($validator->getMessages() as $message) {
echo "$message\n";
}
}
As per the above snippets, user1#email.com cannot register again. Because, that emailaddress is exist in table.
But, i would like to do register with 2site.com. Because, user1#email.com is in 1site.com.
So, user1#email.com cannot register with 1site.com again. But, user1#email.com can register with 2site.com.
How is it possible? Let me know your suggestions.
There are two way to do this.
First using Excluding Record methods
Where you exclude the record of websitename field value.
Zend\Validator\Db\RecordExists and Zend\Validator\Db\NoRecordExists
also provide a means to test the database, excluding a part of the
table, either by providing a where clause as a string, or an array
with the keys “field” and “value”.
$email = 'user#example.com';
$clause = $db->quoteInto('email = ?', $email);
$validator = new Zend\Validator\Db\RecordExists(
array(
'table' => 'users',
'field' => 'username',
'exclude' => $clause
)
);
if ($validator->isValid($username)) {
// username appears to be valid
} else {
// username is invalid; print the reason
$messages = $validator->getMessages();
foreach ($messages as $message) {
echo "$message\n";
}
}
Second by writing your own custom validtor.
You need to extend AbstractDB class and create your own class on directions of RecordExists Class. In your own cust class your can define your own query and pass it to isValid function.
I have created a Custom Validator oposite to Exclude, which is include.
include is reserve word, Now sure if it will work.
check it here
More readings on this
Guidlines 1
Please have look to existing validtor for creating your own custom validatorCustom validator guildline
Chain validator 2
One of the search functions to our website returns far too many results for one page to handle, so I am trying to add the paging function as provided by here: https://github.com/TroyGoode/PagedList
The solution builds properly and the page will load as well, however when I try to conduct a search a "NotSupportedException" is thrown on the page's controller/Index() method:
The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'.
Visual Studio 2010 points to the return statement when this exception is thrown. This is only my second day working in ASP MVC so any and all suggestion are welcome. Thank you!
case "name":
//if no comma, do a combined search by last name and by corporate name.
searchString = searchString.ToUpper();
var lastAgents =
db.Agent.OrderBy(s => s.LastName).Where(s => s.LastName.ToUpper().StartsWith(searchString)).Include(
a => a.AgentIdentification).Include(a => a.SymetraNumberToAgentId);
//end new code
var corp2Agents =
db.Agent.OrderBy(s => s.CorporateName).Where(s => s.CorporateName.ToUpper().StartsWith(searchString)).Include(
a => a.AgentIdentification);
if ((corp2Agents.Count() == 0) & (lastAgents.Count() == 0)) ViewBag.ErrorMessage = "None found in search for Last Names and Companies beginning with " + search1;
else ViewBag.Message = "Results of Last Name and Company Name search. Found " + (corp2Agents.Count() + lastAgents.Count()).ToString();
pageNumber = (page ?? 1);
return View(lastAgents.Union(corp2Agents).ToPagedList(pageNumber, pageSize));
Took forever but I found the answer. Both these statements
var lastAgents =
db.Agent.OrderBy(s => s.LastName).Where(s => s.LastName.ToUpper().StartsWith(searchString)).Include(
a => a.AgentIdentification).Include(a => a.SymetraNumberToAgentId);
//end new code
var corp2Agents =
db.Agent.OrderBy(s => s.CorporateName).Where(s => s.CorporateName.ToUpper().StartsWith(searchString)).Include(
a => a.AgentIdentification);
contain an OrderBy, however this is necessary in the Union statement as well. The final "return" statement is as follows:
return View((lastAgents.Union(corp2Agents)).OrderBy(s => s.sNumber).ToPagedList(pageNumber, pageSize));
Try adding the .OrderBy(s => s.sNumber) in the controller like this:
var lastAgents =
db.Agent.Where(s => s.LastName.ToUpper().StartsWith(searchString)).Include(
a => a.AgentIdentification).Include(a => a.SymetraNumberToAgentId).OrderBy(s => s.sNumber);
//end new code
var corp2Agents =
db.Agent.Where(s => s.CorporateName.ToUpper().StartsWith(searchString)).Include(
a => a.AgentIdentification).OrderBy(s => s.CorporateName);
Can someone tell me how to make a join within magento
Here is the problem:
<?//kleurtjes
$collection= Mage::getModel('faq/faq')->getCollection();
$collection->getSelect()->join(array('faqcat' => $this->getTable('faqcat/faqcat')), 'faqcat.faqcat_id=faq.faqcat_id' , array('faqcat.*'));
?>
i am trying to make a join with the table faqcat where i use the key faqcat_id .
futher i want that faqcat.name + faq.faq_id are being selected cos these are the values i want to use in colums.
<?
protected function _prepareColumns()
{
$this->addColumn('faq_id', array(
'header' => Mage::helper('faq')->__('ID'),
'align' =>'right',
'width' => '50px',
'index' => 'faq_id',
));
$this->addColumn('name', array(
'header' => Mage::helper('faqcat')->__('Titel'),
'align' =>'left',
'index' => 'name',
));
}
?>
after trying 1000 combinations i dont know what to do anymore ... who is willing to help me
this is the complete function:
<?
protected function _prepareCollection()
{
$collection= Mage::getModel('faq/faq')->getCollection();
//$collection->getSelect()->join(array('faqcat' => $this->getTable('faqcat/faqcat')), 'faqcat.faqcat_id=faq.faqcat_id' , array('faqcat.*'));
$id = Mage::getModel('customer/session')->getCustomer()->getId();
$this->setCollection($collection);
// }
return parent::_prepareCollection();
}
?>
just to be clear this is the sql i want to have , but then the magento way
<?//kleurtjes
SELECT faq.faq_id as id, faqcat_name as name
FROM faq
JOIN faqcat
USING ('faqcat_id')
?>
Try this:
$collection->getSelect()
->join($this->getTable('faqcat/faqcat'), "faqcat.faqcat_id = main_table.faqcat_id", array(faqcat.*));
You can see the sql that will actually be run to fetch the collection by:
Mage::log($collection->getSelect()->__toString());
The Varien_Db_Select class is based on Zend_Db_Select, so the Zend documentation is a good reference.
i have just started developing magento extension (loving it) and this is the 2nd part in it where i have to show a grid from two tables. (whew).
but its not that easy after surfing internet a lot i achieved mine result by doing this.
$collection = Mage::getModel('linkdirectory/linkdirectory')->getCollection();
$resource = Mage::getSingleton('core/resource');
$collection->getSelect()
->join(
array('lk'=>$resource->getTableName('linkdirectory/linkcategory')),
'lk.cat_id = main_table.cat_id',
array('lk.cat_title','lk.cat_id')
);
/* mine was showing this */
/SELECT main_table., lk.cat_title, lk.cat_id FROM linkdirectory AS main_table INNER JOIN linkcategory AS lk ON lk.cat_id = main_table.cat_id*/
/* to print the current query */
$collection->printlogquery(true);exit;