![]() |
|
Snippets |
|
complement complex SQL in SYMFONY:
Example 1: SQL to be implemented:
SELECT b.id FROM article_mark a RIGHT JOIN article b ON a.article_id = b.id ORDER BY a.mark DESC,b.CREATED_AT DESC
Symfony implementation:
$c=new Criteria(); $c->addAlias('a', 'article_mark'); //!!!if not using alias of table, the generated sql is not correct $c->addAlias('b', 'article'); $c->addSelectColumn('b.id'); $c->addSelectColumn('a.article_id'); //!!!if one table has no column added, there's no table name after FROM clause;; actually this column is not what I need $c->addDescendingOrderByColumn('a.mark'); $c->addDescendingOrderByColumn('b.CREATED_AT'); $c->addJoin('a.ARTICLE_ID','b.ID','RIGHT JOIN'); $art_marks=ArticlePeer::doSelectRS($c); //!!! doSelect or doSelectOne can't be used
By this way, $art_marks is a MySQL recordset, using $art_marks[0] get value of column b.id;
Example 2: SQL to be implemented:
select SUM(score) from bury group by article_id having article_id=@ARTICLE_ID
Symfony implementation:
$c=new Criteria(); $c->addSelectColumn('SUM(score) as A'); //actually 'as A' has no use $c->addSelectColumn(BuryPeer::SCORE); //!! without this, no table name in generated sql; actually this column is not what I need $c->addGroupByColumn('article_id'); $crit=$c->getNewCriterion(BuryPeer::ARTICLE_ID,$article->getId()); $c->addHaving($crit); $buries=BuryPeer::doSelectRS($c); //only MySQL recordset can be used
using AJAX to check username duplication. there's another submit button on form, should not use submit whole page to check username availability.
in template:
<DIV id='usercheck'> </DIV>
<?php
echo submit_to_remote('ajax_submit', 'Check Username', array(
'update' => 'usercheck',
'url' => '/user/checkusername',
));
in action class, check dupliation:
public function executeCheckusername(){ $username=$this->getRequestParameter('obj_username'); $c = new Criteria(); $c->add(UserPeer::USERNAME, $username); $user = UserPeer::doSelectOne($c); if ($user) { // username already exists $this->setFlash('username_exists', 'y'); return sfView::SUCCESS; } else { $this->setFlash('username_exists', 'n'); return sfView::SUCCESS; } }
in checkusernameSuccess, display error message:
<?php if($sf_flash->get('username_exists') == 'y'){ ?> <FONT COLOR="RED">Username Not Available</FONT> <?php } else { ?> <FONT COLOR="GREEN">Username Available</FONT> <?php } ?>
~~~The table sql statments can't be edited into previous snippet, so paste here
*** table (the following tables have been splited up into 2 tables to use i18n, but the above code doesn't, so either merge these two tables into 1, or setCulture() in above action.class.php code):
-- -- Table structure for table `category` -- CREATE TABLE `category` ( `id` int(11) NOT NULL auto_increment, `parent_id` int(11) default NULL, PRIMARY KEY (`id`), KEY `category_FI_1` (`parent_id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=43 ; -- -- Dumping data for table `category` -- INSERT INTO `category` VALUES (1, NULL); INSERT INTO `category` VALUES (2, NULL); INSERT INTO `category` VALUES (3, NULL); INSERT INTO `category` VALUES (4, NULL); INSERT INTO `category` VALUES (5, NULL); INSERT INTO `category` VALUES (6, NULL); INSERT INTO `category` VALUES (7, NULL); INSERT INTO `category` VALUES (8, 1); INSERT INTO `category` VALUES (9, 1); INSERT INTO `category` VALUES (10, 1); INSERT INTO `category` VALUES (11, 1); INSERT INTO `category` VALUES (12, 1); INSERT INTO `category` VALUES (13, 2); INSERT INTO `category` VALUES (14, 2); INSERT INTO `category` VALUES (15, 2); INSERT INTO `category` VALUES (16, 2); INSERT INTO `category` VALUES (17, 2); INSERT INTO `category` VALUES (18, 3); INSERT INTO `category` VALUES (19, 3); INSERT INTO `category` VALUES (20, 3); INSERT INTO `category` VALUES (21, 3); INSERT INTO `category` VALUES (22, 3); INSERT INTO `category` VALUES (23, 4); INSERT INTO `category` VALUES (24, 4); INSERT INTO `category` VALUES (25, 4); INSERT INTO `category` VALUES (26, 4); INSERT INTO `category` VALUES (27, 4); INSERT INTO `category` VALUES (28, 5); INSERT INTO `category` VALUES (29, 5); INSERT INTO `category` VALUES (30, 5); INSERT INTO `category` VALUES (31, 5); INSERT INTO `category` VALUES (32, 5); INSERT INTO `category` VALUES (33, 6); INSERT INTO `category` VALUES (34, 6); INSERT INTO `category` VALUES (35, 6); INSERT INTO `category` VALUES (36, 6); INSERT INTO `category` VALUES (37, 6); INSERT INTO `category` VALUES (38, 7); INSERT INTO `category` VALUES (39, 7); INSERT INTO `category` VALUES (40, 7); INSERT INTO `category` VALUES (41, 7); INSERT INTO `category` VALUES (42, 7); -- -------------------------------------------------------- -- -- Table structure for table `category_i18n` -- CREATE TABLE `category_i18n` ( `id` int(11) NOT NULL, `culture` varchar(7) NOT NULL, `name` varchar(50) character set utf8 collate utf8_unicode_ci default NULL, `description` varchar(500) character set utf8 collate utf8_unicode_ci default NULL, PRIMARY KEY (`id`,`culture`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; -- -- Dumping data for table `category_i18n` -- INSERT INTO `category_i18n` VALUES (1, 'en', 'German', 'description of German'); INSERT INTO `category_i18n` VALUES (1, 'zh', 'DeGuo', 'DeGuo MiaoShu'); INSERT INTO `category_i18n` VALUES (2, 'en', 'France', 'description of France'); INSERT INTO `category_i18n` VALUES (2, 'zh', 'FaGuo', 'FaGuo MiaoShu'); INSERT INTO `category_i18n` VALUES (3, 'en', 'Argentina', 'description of Argentina'); INSERT INTO `category_i18n` VALUES (3, 'zh', 'AGenTing', 'AGenTing MiaoShu'); INSERT INTO `category_i18n` VALUES (4, 'en', 'Australia', 'description of Australia'); INSERT INTO `category_i18n` VALUES (4, 'zh', 'AoDaLiYa', 'AoDaLiYa MiaoShu'); INSERT INTO `category_i18n` VALUES (5, 'en', 'Brazia', 'description of Brazia'); INSERT INTO `category_i18n` VALUES (5, 'zh', 'BaXi', 'BaXi MiaoShu'); INSERT INTO `category_i18n` VALUES (6, 'en', 'Greece', 'description of Greece'); INSERT INTO `category_i18n` VALUES (6, 'zh', 'XiLa', 'XiLa MiaoShu'); INSERT INTO `category_i18n` VALUES (7, 'en', 'England', 'description of England'); INSERT INTO `category_i18n` VALUES (7, 'zh', 'YingGeLan', 'YingGeLan MiaoShu'); INSERT INTO `category_i18n` VALUES (8, 'en', 'Team1.DE', 'description of Team1.DE'); INSERT INTO `category_i18n` VALUES (8, 'zh', 'ZhuQiuDui1.DeGuo', 'MiaoShu ZhuQiuDui1.DeGuo'); INSERT INTO `category_i18n` VALUES (9, 'en', 'Team2.DE', 'description of Team2.DE'); INSERT INTO `category_i18n` VALUES (9, 'zh', 'ZhuQiuDui2.DeGuo', 'MiaoShu ZhuQiuDui2.DeGuo'); INSERT INTO `category_i18n` VALUES (10, 'en', 'Team3.DE', 'description of Team3.DE'); INSERT INTO `category_i18n` VALUES (10, 'zh', 'ZhuQiuDui3.DeGuo', 'MiaoShu ZhuQiuDui3.DeGuo'); INSERT INTO `category_i18n` VALUES (11, 'en', 'Team4.DE', 'description of Team4.DE'); INSERT INTO `category_i18n` VALUES (11, 'zh', 'ZhuQiuDui4.DeGuo', 'MiaoShu ZhuQiuDui4.DeGuo'); INSERT INTO `category_i18n` VALUES (12, 'en', 'Team5.DE', 'description of Team5.DE'); INSERT INTO `category_i18n` VALUES (12, 'zh', 'ZhuQiuDui5.DeGuo', 'MiaoShu ZhuQiuDui5.DeGuo'); INSERT INTO `category_i18n` VALUES (13, 'en', 'Team1.Fr', 'description of Team1.Fr'); INSERT INTO `category_i18n` VALUES (13, 'zh', 'ZhuQiuDui1.FaGuo', 'MiaoShu ZhuQiuDui1.FaGuo'); INSERT INTO `category_i18n` VALUES (14, 'en', 'Team2.Fr', 'description of Team2.Fr'); INSERT INTO `category_i18n` VALUES (14, 'zh', 'ZhuQiuDui2.FaGuo', 'MiaoShu ZhuQiuDui2.FaGuo'); INSERT INTO `category_i18n` VALUES (15, 'en', 'Team3.Fr', 'description of Team3.Fr'); INSERT INTO `category_i18n` VALUES (15, 'zh', 'ZhuQiuDui3.FaGuo', 'MiaoShu ZhuQiuDui3.FaGuo'); INSERT INTO `category_i18n` VALUES (16, 'en', 'Team4.Fr', 'description of Team4.Fr'); INSERT INTO `category_i18n` VALUES (16, 'zh', 'ZhuQiuDui4.FaGuo', 'MiaoShu ZhuQiuDui4.FaGuo'); INSERT INTO `category_i18n` VALUES (17, 'en', 'Team5.Fr', 'description of Team5.Fr'); INSERT INTO `category_i18n` VALUES (17, 'zh', 'ZhuQiuDui5.FaGuo', 'MiaoShu ZhuQiuDui5.FaGuo'); INSERT INTO `category_i18n` VALUES (18, 'en', 'Team1.AR', 'description of Team1.AR'); INSERT INTO `category_i18n` VALUES (18, 'zh', 'ZhuQiuDui1.AGenTing', 'MiaoShu ZhuQiuDui1.AGenTing'); INSERT INTO `category_i18n` VALUES (19, 'en', 'Team2.AR', 'description of Team2.AR'); INSERT INTO `category_i18n` VALUES (19, 'zh', 'ZhuQiuDui2.AGenTing', 'MiaoShu ZhuQiuDui2.AGenTing'); INSERT INTO `category_i18n` VALUES (20, 'en', 'Team3.AR', 'description of Team3.AR'); INSERT INTO `category_i18n` VALUES (20, 'zh', 'ZhuQiuDui3.AGenTing', 'MiaoShu ZhuQiuDui3.AGenTing'); INSERT INTO `category_i18n` VALUES (21, 'en', 'Team4.AR', 'description of Team4.AR'); INSERT INTO `category_i18n` VALUES (21, 'zh', 'ZhuQiuDui4.AGenTing', 'MiaoShu ZhuQiuDui4.AGenTing'); INSERT INTO `category_i18n` VALUES (22, 'en', 'Team5.AR', 'description of Team5.AR'); INSERT INTO `category_i18n` VALUES (22, 'zh', 'ZhuQiuDui5.AGenTing', 'MiaoShu ZhuQiuDui5.AGenTing'); INSERT INTO `category_i18n` VALUES (23, 'en', 'Team1.AU', 'description of Team1.AU'); INSERT INTO `category_i18n` VALUES (23, 'zh', 'ZhuQiuDui1.AoDaLiYa', 'MiaoShu ZhuQiuDui1.AoDaLiYa'); INSERT INTO `category_i18n` VALUES (24, 'en', 'Team2.AU', 'description of Team2.AU'); INSERT INTO `category_i18n` VALUES (24, 'zh', 'ZhuQiuDui2.AoDaLiYa', 'MiaoShu ZhuQiuDui2.AoDaLiYa'); INSERT INTO `category_i18n` VALUES (25, 'en', 'Team3.AU', 'description of Team3.AU'); INSERT INTO `category_i18n` VALUES (25, 'zh', 'ZhuQiuDui3.AoDaLiYa', 'MiaoShu ZhuQiuDui3.AoDaLiYa'); INSERT INTO `category_i18n` VALUES (26, 'en', 'Team4.AU', 'description of Team4.AU'); INSERT INTO `category_i18n` VALUES (26, 'zh', 'ZhuQiuDui4.AoDaLiYa', 'MiaoShu ZhuQiuDui4.AoDaLiYa'); INSERT INTO `category_i18n` VALUES (27, 'en', 'Team5.AU', 'description of Team5.AU'); INSERT INTO `category_i18n` VALUES (27, 'zh', 'ZhuQiuDui5.AoDaLiYa', 'MiaoShu ZhuQiuDui5.AoDaLiYa'); INSERT INTO `category_i18n` VALUES (28, 'en', 'Team1.BR', 'description of Team1.BR'); INSERT INTO `category_i18n` VALUES (28, 'zh', 'ZhuQiuDui1.BaXi', 'MiaoShu ZhuQiuDui1.BaXi'); INSERT INTO `category_i18n` VALUES (29, 'en', 'Team2.BR', 'description of Team2.BR'); INSERT INTO `category_i18n` VALUES (29, 'zh', 'ZhuQiuDui2.BaXi', 'MiaoShu ZhuQiuDui2.BaXi'); INSERT INTO `category_i18n` VALUES (30, 'en', 'Team3.BR', 'description of Team3.BR'); INSERT INTO `category_i18n` VALUES (30, 'zh', 'ZhuQiuDui3.BaXi', 'MiaoShu ZhuQiuDui3.BaXi'); INSERT INTO `category_i18n` VALUES (31, 'en', 'Team4.BR', 'description of Team4.BR'); INSERT INTO `category_i18n` VALUES (31, 'zh', 'ZhuQiuDui4.BaXi', 'MiaoShu ZhuQiuDui4.BaXi'); INSERT INTO `category_i18n` VALUES (32, 'en', 'Team5.BR', 'description of Team5.BR'); INSERT INTO `category_i18n` VALUES (32, 'zh', 'ZhuQiuDui5.BaXi', 'MiaoShu ZhuQiuDui5.BaXi'); INSERT INTO `category_i18n` VALUES (33, 'en', 'Team1.GR', 'description of Team1.GR'); INSERT INTO `category_i18n` VALUES (33, 'zh', 'ZhuQiuDui1.XiLa', 'MiaoShu ZhuQiuDui1.XiLa'); INSERT INTO `category_i18n` VALUES (34, 'en', 'Team2.GR', 'description of Team2.GR'); INSERT INTO `category_i18n` VALUES (34, 'zh', 'ZhuQiuDui2.XiLa', 'MiaoShu ZhuQiuDui2.XiLa'); INSERT INTO `category_i18n` VALUES (35, 'en', 'Team3.GR', 'description of Team3.GR'); INSERT INTO `category_i18n` VALUES (35, 'zh', 'ZhuQiuDui3.XiLa', 'MiaoShu ZhuQiuDui3.XiLa'); INSERT INTO `category_i18n` VALUES (36, 'en', 'Team4.GR', 'description of Team4.GR'); INSERT INTO `category_i18n` VALUES (36, 'zh', 'ZhuQiuDui4.XiLa', 'MiaoShu ZhuQiuDui4.XiLa'); INSERT INTO `category_i18n` VALUES (37, 'en', 'Team5.GR', 'description of Team5.GR'); INSERT INTO `category_i18n` VALUES (37, 'zh', 'ZhuQiuDui5.XiLa', 'MiaoShu ZhuQiuDui5.XiLa'); INSERT INTO `category_i18n` VALUES (38, 'en', 'Team1.EN', 'description of Team1.EN'); INSERT INTO `category_i18n` VALUES (38, 'zh', 'ZhuQiuDui1.YingGeLan', 'MiaoShu ZhuQiuDui1.YingGeLan'); INSERT INTO `category_i18n` VALUES (39, 'en', 'Team2.EN', 'description of Team2.EN'); INSERT INTO `category_i18n` VALUES (39, 'zh', 'ZhuQiuDui2.YingGeLan', 'MiaoShu ZhuQiuDui2.YingGeLan'); INSERT INTO `category_i18n` VALUES (40, 'en', 'Team3.EN', 'description of Team3.EN'); INSERT INTO `category_i18n` VALUES (40, 'zh', 'ZhuQiuDui3.YingGeLan', 'MiaoShu ZhuQiuDui3.YingGeLan'); INSERT INTO `category_i18n` VALUES (41, 'en', 'Team4.EN', 'description of Team4.EN'); INSERT INTO `category_i18n` VALUES (41, 'zh', 'ZhuQiuDui4.YingGeLan', 'MiaoShu ZhuQiuDui4.YingGeLan'); INSERT INTO `category_i18n` VALUES (42, 'en', 'Team5.EN', 'description of Team5.EN'); INSERT INTO `category_i18n` VALUES (42, 'zh', 'ZhuQiuDui5.YingGeLan', 'MiaoShu ZhuQiuDui5.YingGeLan');
There are two multi-select box, the first one is parent list menu, the second one is child menu; when clicking item in first list, its submenu will appear in second list, then you can multi-select from 2nd list; and you can multi-select items in 1st list by clicking, double-click, ctrl+click, shift+click, all selected items in 1st list will display their children in 2nd list, all deselected items from 1st list will remove their children from 2nd list. This combo list can be used for select HOBBIES, TYPES, CATEGORIES etc.
*** in multiselSuccess.php:
<script type="text/javascript" src="/sf/js/prototype/prototype.js"></script> <body onload="new Ajax.Request('/news/select/level/province', {asynchronous:true, evalScripts:false, onComplete:function(request, json){updateJSON(request,json,1)}}); return false;" >
*** in multiselSuccess.php:
<?php echo select_tag("province",options_for_select(Array(''=>'-Select-')),'multiple=multiple size=10 onmousedown=GetCurrentListValues(this); onchange=javascript:loadCity(\''.sfConfig::get('app_site_url').'news/select/level/city\',this)'); echo select_tag('city[]',options_for_select(Array(''=>'-Select-')),'multiple=multiple size=10'); ?> <div id=statusTxt></div>
*** in view.yml:
selectSuccess: has_layout: off
*** javascript can be written in multiselSuccess.php, or in another javascript file multiselSuccess.js: if written in a seperate file multiselSuccess.js, put it under PROJECT_NAME\web\js\, and in ...\apps\APPLICATION_NAME\config:
javascripts: [multiselSuccess.js ]
<script language="javascript"> <!--// /** * ajax no refresh cascading 2-level menu * */ function loadCity(url,CONTROL) { //load city var strTmp=provinceChanged(CONTROL); //result format: +provinceId or -provinceId var provChg=strTmp.split(","); url=url+"/id/"+provChg[0]; //provChg[0]: item value of first menu; url: /news/select/level/city/id/ItemValueOfFirstMenu new Ajax.Request(url, {asynchronous:true, evalScripts:false, onComplete:function(request, json){updateJSON(request,json,2,provChg[1])}}); return false; } var arrOldValues; function GetCurrentListValues(CONTROL){ var strValues = ""; strValues = GetSelectValues(CONTROL); arrOldValues = strValues.split(",") } function GetSelectValues(CONTROL){ var strTemp = ""; for(var i = 0;i < CONTROL.length;i++){ if(CONTROL.options[i].selected == true){ strTemp += "1,"; } else{ strTemp += "0,"; } } return strTemp; } function provinceChanged(CONTROL){ var strTemp = GetSelectValues(CONTROL); arrNewValues = strTemp.split(","); var sum=0; for(var i=0;i<arrNewValues.length-1;i++){ sum+=eval(arrNewValues[i]); if (sum >= 2){ //more than 1 are selected break; } if (arrNewValues[i] == 1){ //when this condition is met, sum must be 1 var selectedPos=i; } } if (sum==0){ //deselect all by ^Click; remove all from 2nd menu provChg=""+",--"; } else if (sum==1){ //only one selected, click or ctrl+click if (arrOldValues[selectedPos] == 0){ //if this selcted one wasn't selected before, just add; //at this point,arrNewValues[selectedPos] must be 1 removeOptionAll("city"); provChg=CONTROL.options[selectedPos].value+",+"; } else{ //if this selcted one was selected before, remove all others but keep selected of this one removeOptionAll("city"); provChg=CONTROL.options[selectedPos].value+",+"; //???to simplify, just add, previously selected may be lost } } else{ // for(var i=0;i<arrNewValues.length-1;i++){ if (arrNewValues[i] != arrOldValues[i]){ if (arrNewValues[i]==1){ //add a new province provChg=CONTROL.options[i].value+",+"; } else{ //remove a new province provChg=CONTROL.options[i].value+",-"; } } } } return provChg; } /** * ajax no refresh 2-level cascading menu * */ function addOption(objSelectNow,txt,val) { //using W3C syntax add Options for SELECT var objOption = document.createElement("OPTION"); objOption.text= txt; objOption.value=val; objSelectNow.options.add(objOption); } function addOptionGroup(selectId,optGroup) { var objSelect = document.getElementsByTagName("SELECT"); var objSelectNow = objSelect[selectId]; if (selectId=="province"){ objSelectNow.length = 1; } /// add Options group for (i=0; i<optGroup.length; i++) { addOption(objSelectNow, optGroup[i][1], optGroup[i][0]); } } function removeOptionGroup(selectId,optGroup) //optGroup: array of 2nd menu corresponding to deselected item of 1st menu; categoryId=>categoryName { var objSelect = document.getElementsByTagName("SELECT"); var objSelectNow = objSelect[selectId]; for (i=0;i<objSelectNow.length;i++){ if (objSelectNow.options[i].value==optGroup[0][0]){ //the first position to be removed var bgn=i; break; } } /// remove Options for (i=0;i<optGroup.length;i++){ objSelectNow.options.remove(bgn); } } function removeOptionAll(selectId) { var objSelect = document.getElementsByTagName("SELECT"); var objSelectNow = objSelect[selectId]; for (i=1;i<objSelectNow.options.length;){ objSelectNow.options.remove(1); } } function updateJSON(request, json,level,operation){ var responses = json; if (!json){ //if you don't use the json tips then evaluate the renderedText instead var responses = eval('(' + request.responseText + ')'); } if (level==1) //for 1st menu addOptionGroup("province",responses); else if (level==2){ //for 2nd menu if (operation=="+"){ addOptionGroup("city",responses); } else if (operation=="-"){ removeOptionGroup("city",responses); } else if (operation=="--"){ removeOptionAll("city"); } } } --> </script>
*** in actions.classs.php:
public function executeSelect(){ /** * ajax no refresh 2-level cascading menu back-end * */ //load data: $c=new Criteria(); $c->add(CategoryPeer::PARENT_ID,NULL); //get contents for 1st menu $categories=CategoryPeer::doSelect($c); $parent=""; if ($categories){ $i=0; $parent='['; foreach ($categories as $category){ $name=$category->getName(); $id=$category->getId(); $parent=$parent.'["'.$id.'","'.$name.'"],'; //format for 1st menu: [["1","German"],["2","France"],["3","Argentina"]] //retrive records whose parent_id is.. $c=new Criteria(); $c->add(CategoryPeer::PARENT_ID,$category->getId()); $categories_sub=CategoryPeer::doSelect($c); $city[$id]='['; //index of $city[] is category id; format of $city[]:[["48","Team1.Fr"],["49","Team2.Fr"],["50","Team3.Fr"],["51","Team4.Fr"],["52","Team5.Fr"]] foreach ($categories_sub as $category_sub){ $city[$id]=$city[$id].'["'.$category_sub->getId().'","'.$category_sub->getName().'"],'; } $city[$id]=rtrim($city[$id],","); $city[$id].=']'; $i++; } } $parent=rtrim($parent,","); $parent.=']'; $level=$this->getRequestParameter('level'); if($level=="province"||$level==""){ //level=province, output contents for first menu $this->output=$parent; } else if($level=="city"){ //level=city, output contents for second menu $id=$this->getRequestParameter('id'); $this->output=$city[$id]; } else{ //false $this->output="error when getting data"; } return sfView::SUCCESS; }
*** in selectSuccess.php:
<?php echo $output; ?>