![]() |
|
Snippets |
|
test 2
This part seems to not work properly... I can't put my code, even a simple "phpinfo();" :-(
The following view class tries to load the template under directory name of the current culture, then fall back to the default template if such template cannot be found.
So if you access to "index" action of module "foo" and if current user culture is "zh_HK", the class will try to load: "module/foo/templates/zh_HK/indexSuccess.php"
If no such file exist, it will fall back to the default behaviour by loading "module/foo/templates/indexSuccess.php"
class sfCulturePHPView extends sfPHPView { protected $cultureDirectory = ''; public function initialize($context, $moduleName, $actionName, $viewName) { parent::initialize($context, $moduleName, $actionName, $viewName); } public function getDirectory() { if ($this->cultureDirectory) return $this->directory.'/'.$this->cultureDirectory; return $this->directory; } protected function preRenderCheck() { parent::preRenderCheck(); // determine whether the culture-aware template is usable $currentCulture = $this->context->getUser()->getCulture(); $template = $this->directory.'/'.$currentCulture.'/'.$this->template; if (is_readable($template)) $this->cultureDirectory = $currentCulture; else $this->cultureDirectory = ''; } }
All web browsers support the 'text/html' content type. However, since the introduction of XHTML, a new content type has been available that brings the benefits of XML, which is 'application/xhtml+xml' (more info, why do this)
Although not all browsers support 'application/xhtml+xml', fortunately, the designers of the HTTP protocol provided a good solution: the browser tells the server what content types it can accept and which it prefers. So the server is able to choose which content type to serve.
Firefox is one of the browsers that supports 'application/xhtml+xml' and with the new Firefox3 comes incremental rendering, which means that it has fixed the earlier disadvantage in Firefox2 that 'text/html' was faster to render (more info).
The most noticeable advantage of XHTML rendering is that errors are displayed by the browser, meaning that it's easier to identify and fix layout problems caused by muddled content. If your content is ill-formed, Firefox displays a yellow error page indicating where the error was located. This can be a most useful development tool.
So how can we serve 'application/xhtml+xml' content?
Your content has to be written to be XHTML instead of HTML (the W3C website provides helpful information in explaining how to do this). Your pages must include the correct DOCTYPE (how to do this).
Your application has to change the content-type header depending on whether the browser can accept XHTML or not. Obviously, it's useless to send 'application/xhtml+xml' to older browsers that don't support it.
This snippet helps with the second issue. I have written a filter (shown below) to change the response headers depending on what each browser is able to handle.
Create a new class in your lib folder called XHTMLFilter.class.php thus:
<?php class XHTMLFilter extends sfFilter { public function execute ($filterChain) { $applyIn = $this->getParameter('environments', array('dev')); if (!is_array($applyIn)) { throw new sfException("XHTMLFilter param: not an array ".print_r($applyIn, true)); } if (in_array( SF_ENVIRONMENT, $applyIn )) { $accept = $this->context->getRequest()->getAcceptableContentTypes(); if (in_array('application/xhtml+xml', $accept)) { $this->context->getResponse()->setContentType( 'application/xhtml+xml' ); } } $filterChain->execute(); } }
Now add it to your app/config/filters.yml:
rendering: ~
web_debug: ~
security: ~
XHTMLFilter:
class: XHTMLFilter
param:
environments: [ dev ]
cache: ~
common: ~
flash: ~
execution: ~
There is one configuration parameter (environments) that contains an array of the environments to which the filter will apply. By default, only the 'dev' environment is included but you can add any or all of your environments here.
Relating to the post http://www.symfony-project.org/forum/index.php/m/32510/?srch=insert+values+propel
I've created tools to generate SQL.
PS. Done with haste and for postgresSQL.
Can be edited to take in array of objects and form a whole SQL but I don't want to keep a large array of objects.
CREATED_AT, UPDATED_AT forced as NOW()
/** * To generate sql values for insert statement * * @param $object object the object with relavant data * * @return $valueSql string the object values string */ public static function getObjectInsertValue($object) { if(!$object->isNew()) { throw new Exception('ScToolkit::getObjectInsertValue($object) Only usable with new object.'); return ''; } $className = get_class($object); $classPeer = get_class($object->getPeer()); $tableName = ""; eval('$tableName = '.$classPeer.'::TABLE_NAME;'); //For postgres insert (postgres need define Primary Key) $nextId = 'nextval(\''.$tableName.'_seq\')'; $phpNameMap = array(); eval('$phpNameMap = array_flip('.$classPeer.'::getPhpNameMap());'); //For checking primary key $object->setPrimaryKey(1); $object->resetModified(); $object->setPrimaryKey(2); $valueArray = array(); foreach($phpNameMap as $dataKey=>$objectKey) { $isPrimaryKey = false; $columnName = ""; eval('$columnName = '.$classPeer.'::'.$dataKey.';'); if($object->isColumnModified($columnName)) { $isPrimaryKey = true; } if(!$isPrimaryKey) { if($dataKey=='CREATED_AT' || $dataKey=='UPDATED_AT') { $valueArray[] = 'NOW()'; } else { if(is_null($object->getByName($objectKey))) { $valueArray[] = 'NULL'; } else { $data = $object->getByName($objectKey); $wrapper = ""; if(is_string($data)) { $wrapper = "'"; $data = pg_escape_string($data); } $valueArray[] = $wrapper.$data.$wrapper; } } } else { //For postgres insert (postgres need define Primary Key) eval('$valueArray[] = "'.$nextId.'";'); } } $valueStr = '('.implode(", ", $valueArray).')'; return $valueStr; } /** * To generate sql insert into for insert statement * * @param $classPeer string the object class peer string * * @return $intoSql string the object insert into string */ public static function getObjectInsertInto($classPeer) { $classObject = substr($classPeer, 0, -strlen('Peer')); $object = null; eval('$object = new '.$classObject.'();'); //For checking primary key $object->resetModified(); $object->setPrimaryKey(1); $phpNameMap = array(); eval('$phpNameMap = array_flip('.$classPeer.'::getPhpNameMap());'); $intoArray = array(); foreach($phpNameMap as $dataKey=>$objectKey) { $isPrimaryKey = false; $columnName = ""; eval('$columnName = '.$classPeer.'::'.$dataKey.';'); if($object->isColumnModified($columnName)) { $isPrimaryKey = true; } //For postgres insert (postgres need define Primary Key) //if(!$isPrimaryKey) { $intoArray[] = $dataKey; } } $intoStr = '('.implode(", ", $intoArray).')'; return $intoStr; }
How to use.
$inserts = array(); while($creatingObjects) { $object = new ObjectClass(); $object->setTitle("title"); $object->setSummary("summary"); $inserts[] = Toolkit::getObjectInsertValue($object); } $sql = sprintf('INSERT INTO %s %s', ObjectPeer::TABLE_NAME, Toolkit::getObjectInsertInto('ObjectPeer')) . ' VALUES ' . implode(', ', $inserts); $con = Propel::getConnection(); $stmt = $con->createStatement(); $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_NUM);
This filter will automatically add css file with the name of current module.
It's great to have these files saved separately that to have one huge file. (And demo of CSSEdit doesn't allow saving files bigger than 2.5k chars :D)
Just create your cssAdderFilter.class.php, and add it to your filters.yml. Clear cache and you are ready to go.
<?php class cssAdderFilter extends sfFilter { public function execute( $filterChain ) { $context = $this->getContext(); $request = $context->getRequest(); $response = $context->getResponse(); $module = $request->getParameter("module"); $path_to_web = sfConfig::get("sf_web_dir"); $path_to_css = $path_to_web . "/css/" . $module . ".css"; if (file_exists($path_to_css)) { $response->addStylesheet($module.".css"); } $filterChain->execute(); } }