Желаю всем психического здоровья!
В качестве объекта для успокоения нервов и предпраздничного мидитирования предлагаю символ года в виде бумажной коровы (скачать).

Энжой! :)
/**
* Author form.
*
* @package any
* @subpackage form
* @author Your name here
* @version SVN: $Id: sfPropelFormTemplate.php 10377 2008-07-21 07:10:32Z dwhittle $
*/
class myAuthorForm extends BaseAuthorForm
{
public function configure()
{
$this->setWidget('description', new myWidgetFormRichTextarea(array('editor'=>'fck')));
$values = $this->getValues();
$this->setWidget('pic', new myWidgetFormInputFileEditable(
array(
'is_image' => true,
'delete_label' => 'удалить'
)));
//$this->setWidget('pic', new sfWidgetFormInputFile());
$this->setWidget('avatar', new sfWidgetFormInputFile());
/* VALIDATORS */
$this->setValidators(array(
'f_name' => new sfValidatorString(
array(),
array('required' => 'Обязательное поле')
),
'l_name' => new sfValidatorString(
array(),
array('required' => 'Обязательное поле')
),
'email' => new sfValidatorEmail(
$options = array(),
$messages = array(
'invalid' => 'Введите правильный Email',
'required' => false)
),
'pic' => new sfValidatorFile(array(
'required' => false,
'max_size' => '102400', // bytes (1MB)
'mime_types' => array('image/png', 'image/jpeg',)
)),
));
//$this->widgetSchema->setNameFormat('%s');
$this->validatorSchema->setOption('allow_extra_fields', true);
$this->validatorSchema->setOption('filter_extra_fields', false);
}//configure
public function updateObject($values = null)
{
$object = parent::updateObject();
$path = sfConfig::get('sf_root_dir').DIRECTORY_SEPARATOR.
sfConfig::get('sf_web_dir_name').DIRECTORY_SEPARATOR.sfConfig::get('sf_upload_dir');
$object->setPic(str_replace($path.'/', '', $object->getPic()));
return $object;
}
/* do save*/
protected function doSave($con = null){
$values = $this->getValues();
$path = sfConfig::get('sf_root_dir').'/'.
sfConfig::get('sf_web_dir_name').'/'.sfConfig::get('sf_upload_dir');
if (isset($values['pic_delete'])){
$currentFile = $path.'/'.$this->getObject()->getPic();
if (is_file($currentFile)){
unlink($currentFile);
}
$this->getObject()->setPic('');
}
$file = $values['pic'];
if(!empty($file)){
if (file_exists(sfConfig::get('sf_upload_dir').'/'.$this->getObject()->getPic())){
@unlink($this->getObject()->getPic());
}
$filename = sha1($file->getOriginalName()).$file->getExtension($file->getOriginalExtension());
$path = sfConfig::get('sf_root_dir').DIRECTORY_SEPARATOR.sfConfig::get('sf_web_dir_name').DIRECTORY_SEPARATOR.sfConfig::get('sf_upload_dir');
$file->save($path.'/'.$filename);
}
return parent::doSave($con);
}
}//class
/*
* This file is part of the symfony package.
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* sfWidgetFormInputFileEditable represents an upload HTML input tag with the possibility
* to remove a previously uploaded file.
*
* @package symfony
* @subpackage widget
* @author Fabien Potencier
* @version SVN: $Id: sfWidgetFormInputFileEditable.class.php 11544 2008-09-14 17:40:07Z fabien $
*/
class myWidgetFormInputFileEditable extends sfWidgetFormInputFile
{
/**
* Constructor.
*
* Available options:
*
* * file_src: The current image web source path (required)
* * edit_mode: A Boolean: true to enabled edit mode, false otherwise
* * is_image: Whether the file is a displayable image
* * with_delete: Whether to add a delete checkbox or not
* * delete_label: The delete label used by the template
* * template: The HTML template to use to render this widget
* The available placeholders are:
* * input (the image upload widget)
* * delete (the delete checkbox)
* * delete_label (the delete label text)
* * file (the file tag)
*
* In edit mode, this widget renders an additional widget named after the
* file upload widget with a "_delete" suffix. So, when creating a form,
* don't forget to add a validator for this additional field.
*
* @param array $options An array of options
* @param array $attributes An array of default HTML attributes
*
* @see sfWidgetFormInputFile
*/
protected function configure($options = array(), $attributes = array())
{
parent::configure($options, $attributes);
$this->setOption('type', 'file');
$this->setOption('needs_multipart', true);
//$this->addRequiredOption('file_src');
$this->addOption('file_src', '');
$this->addOption('is_image', false);
$this->addOption('edit_mode', true);
$this->addOption('with_delete', true);
$this->addOption('delete_label', 'remove the current file');
$this->addOption('template', '%file% %input% %delete% %delete_label%');
}
/**
* @param string $name The element name
* @param string $value The value displayed in this widget
* @param array $attributes An array of HTML attributes to be merged with the default HTML attributes
* @param array $errors An array of errors for the field
*
* @return string An HTML tag string
*
* @see sfWidgetForm
*/
public function render($name, $value = null, $attributes = array(), $errors = array())
{
$input = parent::render($name, $value, $attributes, $errors);
if (!$this->getOption('edit_mode'))
{
return $input;
}
if ($this->getOption('with_delete')){
$deleteName = ']' == substr($name, -1) ? substr($name, 0, -1).'_delete]' : $name.'_delete';
$delete = $this->renderTag('input', array_merge(array('type' => 'checkbox', 'name' => $deleteName), $attributes));
$deleteLabel = $this->renderContentTag('span', $this->getOption('delete_label'), array_merge(array('for' => $this->generateId($deleteName))));
} else {
$delete = '';
$deleteLabel = '';
}
if ($value){
$picLink = " || <a class='thickbox' target='_blank' href='/uploads/".$value."'>show me</a>";
} else {
$picLink = "";
$delete = '';
$deleteLabel = '';
}
return strtr($this->getOption('template'), array(
'%input%' => $input,
'%delete%' => $delete,
'%delete_label%' => $deleteLabel,
'%file%' => $this->getFileAsTag($attributes, $value))
).$picLink;
}
protected function getFileAsTag($attributes, $value=null)
{
if ($this->getOption('is_image'))
{
return false !== $value ? $this->renderTag('img', array_merge(array('src' => $value)), $attributes) : '';
}
else
{
return $this->getOption('file_src');
}
}
}
default:
http_metas:
content-type: text/html
metas:
title: Admin
stylesheets: [main, thickbox]
javascripts: [jq/jquery.pack.js, jq/thickbox.pack.js]
.error_list { color: #ff0000; }
.errorField{
background: #ffffcc; border: 2px solid red;
}
.okField{
background: #ffffcc; border: 2px solid lightgreen;
}
.inputField{
background: #ffffff;
}
#loginForm {
display: none;
background: khaki; width: 280px;
position: absolute;
z-index: 9999; font-family: Tahoma; font-size: 12px;
border: 0px solid red;
}
#loginFormHeader {
background: #cccc33; padding: 10px;
border-bottom: 1px solid gray;
font-weight: bold;
}
#loginFormBody {
border-top: 1px solid #ececec;
border-bottom: 1px solid gray;
padding: 4px 0px 4px 0px;
}
#loginFormPic {
padding: 10px 0px 0px 10px;
display: block;
float: left;
}
#loginFormBody ul{
float: left;
display: block;
border: 0px solid navy;
padding: 4px; list-style: none;
}
#loginFormBody ul li{
border: 0px solid #f63;
padding: 4px;
}
#loginFormBody label
{
display: block;
border: 0px solid green;
padding: 0 1em 3px 0;
float: left;
text-align: left;
width: 40px;
color: black;
font-weight: normal !important;
}
#loginFormFooter {
padding: 10px;
text-align: center;
border-top: 1px solid #ececec;
}
signinSuccess:
javascripts: [jq/jquery.pack.js, jq/jquery.dropshadow.js]
stylesheets: [main, myGuard]
metas:
title: login
<?php $errorFieldClass = "errorField" ?>
<?php $defaultFieldClass = ($sf_request->isMethod('post') ? "okField" : "inputField" )?>
<form action="<?php echo url_for('@sf_guard_signin') ?>"
method="post">
<div id="loginForm">
<div id="loginFormHeader">Требуется авторизация</div>
<div id="loginFormBody">
<div id="loginFormPic"><img src="/sf/sf_default/images/icons/lock48.png" /></div>
<ul>
<li><label for="signin_username">Логин:</label>
<?php echo $form['username']->render(
array(
'class' => $form['username']->hasError() ? $errorFieldClass : $defaultFieldClass))
?>
</li>
<li><label for="signin_password">Пароль:</label>
<?php echo $form['password']->render(
array(
'class' => $form['password']->hasError() ? $errorFieldClass : $defaultFieldClass))
?>
</li>
<li><label for="signin_remember"></label>
<?php echo $form['remember']->render() ?> Запомнить?
</li>
</ul>
<br clear="all" />
</div>
<div id="loginFormFooter">
<input type="submit" value="войти" />
</div>
</div>
</form>
<script>
$(document).ready(function() {
$("#loginForm").hide();
var popupX = Math.round( ($(window).width() - $("#loginForm").width()) / 2) ;
var popupY = $(document).scrollTop() + Math.round($(window).height()/2) - Math.round($("#loginForm").height()/2);
$("#loginForm").css({top: popupY+"px", left: popupX+"px"});
$("#signin_username").focus();
$("#loginForm").show();
$("#loginForm").dropShadow();//{left: -2, top: -2, blur: 4, color: "#03f"}
});
</script>
500 | Internal Server Error | sfConfigurationException
The route "articles_collection" does not exist.
articles_collection:
url: /article/:action/*
articles:
class: sfPropelRouteCollection
options:
model: Article
module: article
with_show: false
collection_actions: { filter: post, batch: post }
articles:
class: sfPropelRouteCollection
options:
model: BlogArticle
module: article
collection_actions: { filter: post, batch: post }
<?php
/*
* widget displays nested tree in listbox
* based on symfony 1.1 and Propel 1.3
* 28-okt-2008 by Vit <228vit@gmail.com>
*/
class myWidgetFormPropelSelectTree extends sfWidgetFormSelect
{
/**
* @see sfWidget
*/
public function __construct($options = array(), $attributes = array())
{
$options['choices'] = new sfCallable(array($this, 'getChoices'));
parent::__construct($options, $attributes);
}
/**
* Constructor.
*
* Available options:
*
* * model: The model class (required)
* * add_empty: Whether to add a first empty value or not (false by default)
* If the option is not a Boolean, the value will be used as the text value
* * method: The method to use to display object values (__toString by default)
* * order_by: An array composed of two fields:
* * The column to order by the results (must be in the PhpName format)
* * asc or desc
* * criteria: A criteria to use when retrieving objects
* * connection: The Propel connection to use (null by default)
* * multiple: true if the select tag must allow multiple selections
*
* @see sfWidgetFormSelect
*/
protected function configure($options = array(), $attributes = array())
{
$this->addRequiredOption('model');
$this->addOption('add_empty', false);
$this->addOption('method', '__toString');
$this->addOption('order_by', null);//no needed, tree must be sorted
$this->addOption('criteria', null);
$this->addOption('connection', null);
$this->addOption('multiple', false);
parent::configure($options, $attributes);
}
/**
* Returns the choices associated to the model.
*
* @return array An array of choices
*/
public function getChoices()
{
$choices = array();
if (false !== $this->getOption('add_empty'))
{
$choices[''] = true === $this->getOption('add_empty') ? '' : $this->getOption('add_empty');
}
$class = $this->getOption('model').'Peer';
$criteria = is_null($this->getOption('criteria')) ? new Criteria() : clone $this->getOption('criteria');
$method = $this->getOption('method');
if (!method_exists($this->getOption('model'), $method))
{
throw new RuntimeException(sprintf('Class "%s" must implement a "%s" method to be rendered in a "%s" widget', $this->getOption('model'), $method, __CLASS__));
}
//get all SCOPEs from a tree
$cr = new Criteria;
$method2 = 'addAscendingOrderByColumn';
$cr->addAscendingOrderByColumn(
call_user_func(array($class, 'translateFieldName'),
'Scope',
BasePeer::TYPE_PHPNAME, BasePeer::TYPE_COLNAME)
);
$cr->addGroupByColumn(
call_user_func(array($class, 'translateFieldName'),
'Scope',
BasePeer::TYPE_PHPNAME, BasePeer::TYPE_COLNAME)
);
$scopes = call_user_func(array($class, 'doSelect'), $cr, $this->getOption('connection'));
$scopesCnt = count($scopes)-1;
//loop over scopes
foreach ($scopes as $currScope => $scope){
//retrieve tree for current scope
//TreePeer::retrieveTree($scope->getScope());
$tree = call_user_func(array($class, 'retrieveTree'), $scope->getScope(), $this->getOption('connection'));
//start iterator
$it = new myTreeListboxOptions($tree);
//loop over childs
foreach ($it as $m){
//store attributes in arrays, to build row for listbox
$siblings[$m->getLevel()] = intval($m->hasNextSibling());
$childs[$m->getLevel()] = intval($m->hasChildren());
$currLevel = $m->getLevel();
$connectors = "";//extra string which contains connectors:
$this->setWidgets(array(
'id' => new sfWidgetFormInputHidden(),
'name' => new sfWidgetFormInput(),
...
'parent' => new myWidgetFormPropelSelectTree(
array(
'model' => 'Menu',
'add_empty' => 'root')),
));
$this->widgetSchema->setNameFormat('%s');
$this->validatorSchema->setOption('allow_extra_fields', true);
$this->validatorSchema->setOption('filter_extra_fields', false);
if ($this->form->isValid()){
$tree = new Menu();
$tree->setName($request->getParameter('name'));
$parent = $request->getParameter('parent');
//get max scope
$nextScope = 0;
$c = new Criteria;
$c->clearSelectColumns()->addSelectColumn('MAX(' . MenuPeer::SCOPE . ')');
$stmt = MenuPeer::doSelectStmt($c);
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
$nextScope = $row[0] + 1;
}
$nextScope = (is_null($nextScope) ? 1 : $nextScope);
if (empty($parent)){
$tree->makeRoot();
$tree->setScopeIdValue($nextScope);
} else {
$root = MenuPeer::retrieveByPK($parent);
$tree->insertAsLastChildOf($root);
}
$tree->save();
}//if valid
<?php for($i = 144; $i <= 175; $i++): ?>
<a href="getModuleName()."/list?letter=".chr($i)) ?>">
<?php echo chr(208).chr($i)?></a>
<?php endfor; ?>
<?php for($i = 144; $i <= 175; $i++): ?>
<a href="<?php echo url_for($this->getModuleName()."/list?letter=".chr(208).chr($i)) ?>">
<?php echo chr(208).chr($i)?></a>
<?php if ($i == 149): ?>
<a href="<?php echo url_for($this->getModuleName()."/list?letter=".chr(208).chr(129)) ?>">
<?php echo chr(208).chr(129)?></a>
<?php endif; ?>
<?php endfor; ?>
//было
class Categorie extends BaseCategorie
//стало
class Categorie extends BaseCategorieNestedSet
default:
...
javascripts: [jq/jquery.pack.js]
<script>
jQuery(document).ready(function($){
$("body").after("<div id='result_div'></div>");
$("#result_div").html("<img style='padding: 20px' src='/images/loading.gif' align='absmiddle' /> обработка...");
$("#result_div").hide();
$("#result_div").css({
"background-color": "#ffffcc",
"opacity": "0.7",
"width": "40%",
"height": "auto",
"font-family": "Arial Tahoma",
"text-align": "center",
"vertical-align": "middle",
"border": "1px solid silver",
"position": "absolute",
"top": "40%",
"left": "30%",
"z-index": "9999"
});
});
</script>
<center>
<?php echo
link_to(
image_tag(sfConfig::get('sf_admin_web_dir')."/images/".
($myObject->getIsPublished() ? 'ok.png' : 'cancel.png'),
array('id' => 'switch_status_'.$myObject->getId())
),
"my_module/switchStatus?id=".$myObject->getId(),
array(
'class' => 'switch_status',
'rel' => 'switch_status_'.$myObject->getId(),
'pic_dir' => sfConfig::get('sf_admin_web_dir')."/images/",
)
);//link to
?>
</center>
<script>
$(document).ready(function() {
$(".switch_status").each( function (){
$(this).click( function (){
var popupX = Math.round( ($(window).width() - $("#result_div").width()) / 2) ;
var popupY = $(document).scrollTop() + Math.round($(window).height()/2) -
Math.round($("#result_div").height()/2);
$("#result_div").css({top: popupY+"px", left: popupX+"px"});
var pic_dir = $(this).attr("pic_dir")
var pic_id = $(this).attr("rel")
$("#result_div").slideDown("slow");
$.ajax({
type: "POST",
url: $(this).attr('href'),
data: "",
success: function(msg){
var pic_name = (msg == 1 ? "ok" : "cancel") + ".png"
$("#"+pic_id).attr("src", pic_dir + "/" + pic_name)
$("#result_div").slideUp("slow");
}
});//ajax
return false;
})//click
})//each
});
</script>
public function executeSwitchStatus($request){
$myObject = xxxPeer::retrieveByPk($this->getRequestParameter('id'));
$currentStatus = $myObject->getIsPublished();
$newStatus = ($currentStatus == 1 ? 0 : 1);
$myObject->setIsPublished($newStatus);
$myObject->save();
$isAjax = $request->isXmlHttpRequest();
if ($isAjax){
return $this->renderText($newStatus);
} else {
//do something if not AJAX
}//if
}//change status
<center>
getIsPublished() ?
image_tag(sfConfig::get('sf_admin_web_dir').'/images/ok.png') :
image_tag(sfConfig::get('sf_admin_web_dir').'/images/cancel.png')
?>
</center>
list:
fields:
...
is_published: { name: Статус }
...
display: [ ..., _is_published ]
$ cd /path/to/project/root/
$ svn co http://svn.symfony-project.com/plugins/sfPropelPlugin/branches/1.3/[::space::]plugins/sfPropelPlugin
$this->validatorSchema->setPostValidator(new
sfValidatorPropelUnique(array(
'model' => 'Users',
'column' => array('login')),
array(
'invalid' => 'Такой логин уже есть.'
)
));
class FeedbackUsers extends BaseFeedbackUsers
{
public function __toString(){
return $this->getName();
}
}
class FeedbackLogForm extends BaseFeedbackLogForm
{
public function configure()
{
$this->setWidgets(array(
'id' => new sfWidgetFormInputHidden(),
'feedback_user_id' => new sfWidgetFormPropelSelect(array('model' => 'FeedbackUsers', 'add_empty' => true)),
'name' => new sfWidgetFormInput(),
'email' => new sfWidgetFormInput(),
'subject' => new sfWidgetFormInput(),
'content' => new sfWidgetFormTextarea(),
'get_answer' => new sfWidgetFormInputCheckbox(),
));
$this->widgetSchema->setLabels(array(
'feedback_user_id' => 'Кому',
'name' => 'Ваше Ф.И.О.',
'content' => 'Вопрос',
'email' => 'Ваш Email',
'subject' => 'Заголовок письма',
'get_answer' => 'Получить ответ на Email',
));
}//configure
}//class
$this->widgetSchema->setHelps(array(
'feedback_user_id' => ' * ',
'name' => ' * ',
'content' => ' * ',
'email' => ' * ',
'subject' => ' * ',
'get_answer' => ' да ',
));
$myDecorator = new sfFeedbackFormDecorator($this->getWidgetSchema());
$this->getWidgetSchema()->addFormFormatter('custom', $myDecorator);
$this->widgetSchema->setFormFormatterName('custom');
/*
* CUSTOM DECORATOR
*/
class sfFeedbackFormDecorator extends sfWidgetFormSchemaFormatter {
protected
$rowFormat = "
%hidden_fields%
%label%
%field% %help%
\n",
$helpFormat = '%help%',
$errorRowFormat = "\n%errors%\n",
$errorListFormatInARow = " \n%errors% \n",
$errorRowFormatInARow = " %error%\n",
$namedErrorRowFormatInARow = " %name%: %error% \n",
$decoratorFormat = "";
}// decorator class
propel:
sf_feedback_users:
_attributes: { phpName: FeedbackUsers }
id: { type: integer, required: true,primaryKey: true, autoIncrement: true }
name: { type: varchar(255) }
email: { type: varchar(255) }
subject: { type: varchar(255) }
sf_feedback_log:
_attributes: { phpName: FeedbackLog }
id: { type: integer, required: true, primaryKey: true, autoIncrement: true }
feedback_user_id: { phpName: FeedbackUserId, type: integer, foreignTable: sf_feedback_users, foreignReference: id }
name: { type: varchar(255) }
email: { type: varchar(255) }
subject: { type: varchar(255) }
content: { type: longvarchar }
is_published: { type: boolean, default: 0 }
get_answer: { type: boolean, default: 0 }
created_at: ~
updated_at: ~
ServerName minisite
DocumentRoot "C:\www\sfprojects\minisite\web"
DirectoryIndex index.php
Alias /sf c:\php\data\symfony\web\sf
AllowOverride All
Allow from All
AllowOverride All
Allow from All