goncin@wordpress.com:~$ _

Linux, programação e toda sorte de nerdices

Arquivos de tags: yii framework

Integrando WordPress e Yii Framework: uma nova abordagem

Artigo publicado originalmente em inglês no wiki do Yii
Framework
, em 1º de julho de 2011.

Parece que muitas pessoas andam tentando fazer com que o WordPress e o Yii Framework trabalhem em conjunto. Eu me deparei com o mesmo problema, mas agora creio que o resolvi, após muito quebrar a cuca e gastar inúmeras horas de trabalho.

Meu ponto de partida foi a leitura dos artigos (em inglês) do imasia e do isekream. O princípio de ambas as pesquisas é chamar a aplicação Yii de dentro do WordPress. A solução que proponho coloca-se na mão contrária: utilizar o WordPress como modelo de página para a aplicação Yii, de modo que o usuário final nem perceberá que saiu do primeiro e foi parar na segunda.

Vamos em frente.

No WordPress

Minha instalação do WordPress usa um tema-filho do Twentyten (o padrão do WordPress 3.x). Para os efeitos deste tutorial, assumamos que nossa instalação do WordPress está em http://seuservidor.com.br/wp. Ao aplicá-lo, altere o caminho de acordo com sua situação.

O primeiro passo é criar um arquivo na pasta do seu tema do WP, e chamá-lo yii-template.php.

Arquivo: [raiz-wp]/wp-content/themes/[seutema]/yii-template.php

<?php
/**
 * Template Name: Yii Template
 *
 * Template for Yii-powered pages
 *
 * The "Template Name:" bit above allows this to be selectable
 * from a dropdown menu on the edit page screen.
 *
 * @package WordPress
 * @subpackage Twenty_Ten
 * @since Twenty Ten 1.0
 */
get_header();
?>
 
<div id="container">
  <div id="content" role="main">
 
    <?php
    /*
     * O marcador de lugar abaixo será substituído mais tarde pelo conteúdo gerado pelo Yii.
     */
    ?>
    <!-- ###yii-content-placeholder### -->
 
  </div><!-- #content -->
</div><!-- #container -->
 
<?php get_sidebar(); ?>
<?php get_footer(); ?>

Acabamos de criar um novo modelo para páginas do WordPress.

O passo seguinte é criar uma página no WordPress que use o modelo recém-criado. Acesse o painel administrativo do seu WP, crie uma página e selecione “Yii Template” (deve estar listado) como modelo da página. Informe yiipage no título e deixe o conteúdo da página em branco. Após salvar, você deverá ser capaz de ver a página usando o endereço http://seuservidor.com.br/wp/yiipage.

Isso é tudo o que tínhamos que fazer no WordPress.

No Yii

Crie uma aplicação Yii (usando yiic) sob a raiz da sua instalação do WP, numa pasta chamada yii. Você deverá ver a conhecida página inicial do Yii ao acessar http://seuservidor.com.br/wp/yii.

We’ll need a custom ClientScript class. Let’s create it under [yii-root]/protected/components.

Teremos que criar nossa própria classe ClientScript. Vamos fazê-lo sob  [raiz-yii]/protected/components.

Arquivo: [raiz-yii]/protected/components/ClientScript.php

<?php
 
class ClientScript extends CClientScript {
 
  public function renderHead(&$output) {
    $html = '';
    foreach ($this->metaTags as $meta) $html.=CHtml::metaTag($meta['content'], null, null, $meta) . "\n";
    foreach ($this->linkTags as $link) $html.=CHtml::linkTag(null, null, null, null, $link) . "\n";    
    foreach ($this->cssFiles as $url => $media) $html.=CHtml::cssFile($url, $media) . "\n";
    foreach ($this->css as $css) $html.=CHtml::css($css[0], $css[1]) . "\n";
    if ($this->enableJavaScript) {
      if (isset($this->scriptFiles[self::POS_HEAD])) {
        foreach ($this->scriptFiles[self::POS_HEAD] as $scriptFile) $html.=CHtml::scriptFile($scriptFile) . "\n";
      }

      if (isset($this->scripts[self::POS_HEAD])) $html.=CHtml::script(implode("\n", $this->scripts[self::POS_HEAD])) . "\n";
    }

    if ($html !== '') {
      $count = 0;
      /*
       * A linha abaixo garante que tudo o que for registrado pelo Yii no POS_HEAD irá imediatamente
       * antes do final do cabeçalho (). Dessa forma, os estilos e scripts do Yii serão
       * renderizados *ABAIXO* e *DEPOIS* daqueles do WordPress.
       *
       * A linha original na classe ancestral era assim:
       * $output = preg_replace('/(]*>|)/is', '$1', $output, 1, $count);
       *
       */
      $output = preg_replace('/()/is', '$1', $output, 1, $count);
      if ($count) $output = str_replace('', $html, $output);
      else $output=$html . $output;
    }
  }
 }
?>

Será necessário também sobrepor o método CController.beforeRender(). Isso pode ser feito no arquivo Controller.php, que já existe em [raiz-yii]/protected/components.

Arquivo: [raiz-yii]/protected/components/Controller.php

<?php
/**
 * Controller is the customized base controller class.
 * All controller classes for this application should extend from this base class.
 */
class Controller extends CController
{
    /**
     * @var string the default layout for the controller view. Defaults to '//layouts/column1',
     * meaning using a single column layout. See 'protected/views/layouts/column1.php'.
     */
    public $layout='//layouts/column1';
    /**
     * @var array context menu items. This property will be assigned to {@link CMenu::items}.
     */
    public $menu=array();
    /**
     * @var array the breadcrumbs of the current page. The value of this property will
     * be assigned to {@link CBreadcrumbs::links}. Please refer to {@link CBreadcrumbs::links}
     * for more details on how to specify this property.
     */
    public $breadcrumbs=array();
 
  protected function beforeRender($view) {
 
    /* 
     * Let's prevent Yii from registering jQuery library. We'll stick with
     * the jQuery registered by WordPress.
    */
    Yii::app()->clientScript->scriptMap=array(
      'jquery.js'=>false,
      'jquery.min.js'=>false,
    );
    /*
     * O WordPress trabalha com a jQuery no modo "sem-conflito", i. e., ele não define o apelido $
     * para o objeto jQuery. No entanto, muitos scripts e plugin do Yii supõem que $ aponta para a
     * jQuery, de modo que precisamos fazer essa associação nós mesmos.
     */
    if(! Yii::app()->clientScript->isScriptRegistered('jquery-alias', CClientScript::POS_HEAD)) {
      Yii::app()->clientScript->registerScript('jquery-alias', 'var $ = jQuery', CClientScript::POS_HEAD);
    }

    /*
     * Para manter a coerência visual entre as páginas comuns do WordPress e aquelas turbinadas
     * pelo Yii, devemos utilizar o CSS fornecido pelo tema do WordPress. Contudo, o Yii usa
     * algumas classes CSS específicas para formulários, então é uma boa ideia registrar o
     * arquivo que as contém.
     */
    Yii::app()->clientScript->registerCssFile(Yii::app()->request->baseUrl . '/css/form.css');

    return parent::beforeRender($view);
  }

}
?>

Agora, a pedra fundamental da ideia toda. Vamos alterar o arquivo principal do layout do Yii, para buscar a página do WordPress que preparamos previamente, e substituir o marcador de lugar pelo conteúdo gerado pelo framework.

Arquivo: [raiz-yii]/protected/views/layouts/main.php

<?php
  /*
   * Aqui reside o cerne da mágica. Ao invés de usar o HTML do arquivo principal de
   * layout fornecido pelo Yii, buscamos a página especial do WordPress (como uma string)
   * e substituímos o marcador de lugar pelo conteúdo real.
   */

  echo str_replace('<!-- ###yii-content-placeholder### -->',
    $content, file_get_contents('http://seuservidor.com.br/wp/yiipage'));

  /* NÃO SE ESQUÇA DE APAGAR O CONTEÚDO DA PÁGINA ORIGINAL ;) */

?>

Por fim, vamos dizer ao Yii para usar nossa classe ClientScript personalizada.

Arquivo: [raiz-yii]/protected/config/main.php

<?php   
    (...)   'components'=-->array(
    /*
     * Vamos usar nosso próprio ClientScript (application.components.ClientScript).
     */
    'clientScript' => array(
      'class' => 'ClientScript'
    ),
  (...)
?>

E isso é tudo. Você deverá conseguir ver sua aplicação Yii com tema WordPress acessando http://seuservidor.com.br/wp/yii, e até mesmo fazer login mediante http://seuservidor.com.br/wp/yii/index.php?r=site/login. Adicionalmente, você pode ajustar sua configuração do Yii para usar URLs de caminho e ocultar o nome do script (assim, seus URLs se parecerão com http://seuservidor.com.br/wp/yii/controller/action). E sim, o AJAX funciona! *__*

De volta ao WordPress, a tarefa final é criar itens de menu (como links) apontando para as páginas turbinadas pelo Yii.

Espero que isto seja tão útil para você quanto foi para mim. Saudações!

O Yii Framework e os “models” (modelos)

Dando seguimento à série de artigos sobre o Yii Framework, desejo compartilhar algumas reflexões acerca dos modelos (models) do padrão de desenvolvimento MVC e de como o Yii Framework implementa o conceito.

Para deixar as coisas mais claras, tomei a liberdade de traduzir a definição de modelo constante deste artigo da Wikipédia de língua inglesa (quase sempre mais completa que a versão lusófona):

O modelo é utilizado para gerenciar informações e notificar os observadores quando a informação é alterada. O modelo é a representação dos dados específica de um negócio, sobre os quais a aplicação trabalha. A lógica de negócio dá significado aos dados brutos (como, por exemplo, determinar se hoje é o dia do aniversário do usuário, ou os totais, impostos e valores de frete para itens de um carrinho de compras). Quando o estado do modelo se altera, este notifica suas visões [views] associadas, de forma que elas possam ser atualizadas.

Várias aplicações usam um mecanismo de armazenamento persistente, como um banco de dados, para guardar os dados. O padrão MVC não menciona especificamente a camada de acesso aos dados, porque se supõe que ela esteja sob o modelo ou encapsulada por este. Modelos não são objetos de acesso a dados; contudo, em aplicações muito simples, com pouca lógica de negócio, não há nenhuma distinção efetiva a se fazer. O Active Record é um padrão de desenvolvimento bem aceito e que une o código da lógica de negócios e o de acesso aos dados – um modelo que sabe como persistir a si mesmo.

Do que foi abordado acima, aprofundemos dois tópicos.

1. O modelo nem sempre está relacionado a um objeto de banco de dados

Isso pode soar estranho, mas basta pensar um pouco para dar razão à assertiva. O ciclo de vida de uma aplicação MVC é, basicamente, coletar dados por intermédio de um formulário (visão, view), filtrá-los segundo as regras de negócio (o que é feito no controlador – controller) e armazená-los para posterior consulta, usando os modelos (models) para tanto.

Há ocasiões, no entanto, em que os dados coletados não precisam ou não devem ser armazenados – eles são necessários apenas em uma etapa intermediária do processamento. Talvez o exemplo mais típico dessa situação sejam os formulários de login, nos quais coletamos um nome de usuário e uma senha, que servem à autenticação/autorização. Depois disso, o nome do usuário (ou seu código, dependendo da lógica implementada) é, no máximo, armazenado num cookie ou num objeto de sessão. Armazenar a senha seria um total contrassenso, por questões de segurança.

O que nos impede, então, de representar os dados de um formulário de login como um modelo? É exatamente isso que o Yii Framework faz. Em todo projeto iniciado com o auxílio da ferramenta de linha de comando yiic, é gerado um modelo chamado LoginForm (na pasta protected/models), cujo conteúdo é o seguinte:

class LoginForm extends CFormModel
{
	public $username;
	public $password;
	public $rememberMe;

	private $_identity;

	/**
	 * Declares the validation rules.
	 * The rules state that username and password are required,
	 * and password needs to be authenticated.
	 */
	public function rules()
	{
		return array(
			// username and password are required
			array('username, password', 'required'),
			// rememberMe needs to be a boolean
			array('rememberMe', 'boolean'),
			// password needs to be authenticated
			array('password', 'authenticate', 'skipOnError'=>true),
		);
	}

	/**
	 * Declares attribute labels.
	 */
	public function attributeLabels()
	{
		return array(
			'rememberMe'=>'Remember me next time',
		);
	}

	/**
	 * Authenticates the password.
	 * This is the 'authenticate' validator as declared in rules().
	 */
	public function authenticate($attribute,$params)
	{
		$this->_identity=new UserIdentity($this->username,$this->password);
		if(!$this->_identity->authenticate())
			$this->addError('password','Incorrect username or password.');
	}

	/**
	 * Logs in the user using the given username and password in the model.
	 * @return boolean whether login is successful
	 */
	public function login()
	{
		if($this->_identity===null)
		{
			$this->_identity=new UserIdentity($this->username,$this->password);
			$this->_identity->authenticate();
		}
		if($this->_identity->errorCode===UserIdentity::ERROR_NONE)
		{
			$duration=$this->rememberMe ? 3600*24*30 : 0; // 30 days
			Yii::app()->user->login($this->_identity,$duration);
			return true;
		}
		else
			return false;
	}
}

A classe CFormModel, na hierarquia do Yii Framework, descende de CModel. Estão ali alguns métodos que costumamos ver nos posts anteriores, como o rules(), que estabelece as regras de validação para os dados, e o attributeLabels(), no qual podemos definir os nomes dos campos na linguagem natural do usuário.

Os dados de login são colhidos e processados, mas nunca armazenados em banco de dados – mesmo porque nem a classe CFormModel, nem sua ancestral, CModel, implementam um método save(). Pelo “jeitão de ser” do Yii Framework, CFormModel deve ser usado toda vez que os dados do formulário não serão armazenados (ao menos diretamente) num banco de dados. Para o trabalho com banco de dados, utilizamos o CActiveRecord.

2. O Active Record reúne em si regras de negócio e código de acesso a dados

O quão chocante lhe parece esta afirmação? Trata-se, é verdade, de uma quebra do paradigma MVC, que preconiza que as regras de negócio devem residir unicamente no controlador (controller). Ponderemos, porém: validação de dados é, em última análise, regra de negócio NOTA MENTAL: escrever um post sobre validação de dados no Yii Framework. E, se esses dados foram ou serão armazenados em banco de dados, a validação precisa obedecer, necessariamente, a definição da estrutura do BD, bem como as características e limitações do SGBD correspondente.

Logo, faz todo o sentido deixar que o próprio modelo verifique se a informação a ser armazenada num campo definido como VARCHAR(100) não ultrapassa esse comprimento. Podemos chamar isso, grosso modo, de forma. O controlador poderia ter-se encarregado de checar essa mesma informação quanto ao aspecto do conteúdo: é um endereço existente? É um nome de pessoa válido? É um município dentro da área de representação da empresa?

Por isso, e para poupar o precioso tempo do desenvolvedor, é que o Yii Framework mantém as regras de validação de dados, quanto à sua forma, no modelo (clique aqui para ver o exemplo de um código de modelo gerado a partir de um objeto de banco de dados), refletindo, sempre que possível, as regras já definidas no BD (tais quais campos requeridos, comprimento máximo, tipo de valor – numérico, alfanumérico, etc.). Tudo isso é implementado estendendo-se a classe CActiveRecord que, por seu turno, também estende CModel.

Concluindo…

O Yii Framework nos leva a repensar o conceito de modelo, desprendendo-o da correlação, julgada muitas vezes  necessária, com um objeto de banco de dados. Com isso, as possibilidades de uso dos modelos ampliam-se, como é o caso do formulário de login anteriormente citado.

O framework também implementa de forma elegante o padrão de desenvolvimento Active Record, encarregando os modelos gerados a partir de estruturas de bancos de dados da validação formal das informações, poupando o desenvolvedor de escrever código para isso 8) .

Para saber mais

  • The Definitive Guide to Yii (em português)

Entendendo as “relations” (relações) do Yii Framework

No post em que apresentei o Yii Framework, demonstrei a capacidade que este possui de gerar o código dos modelos para o padrão de desenvolvimento MVC a partir da estrutura do banco de dados. Hoje vou um passo além, para mostrar que o código gerado reflete não apenas os atributos, mas também as relações (foreign keys) existentes entre as tabelas do BD.

Consideremos, pois, uma estrutura de dados bem simples:

A tabela 'aluno' possui uma chave estrangeira N para 1 em 'escola'

A tabela 'aluno' possui uma chave estrangeira N para 1 em 'escola'

Nessa estrutura hipotética, cada aluno está vinculado a uma escola; por óbvio, uma escola pode possuir zero ou mais alunos. Na UML, esse tipo de relação é denominado dependência, como nos ensina o companheiro #SouDev Edgard Davidson. A partir dessas informações, o Gii (scaffolder do Yii Framework – veja aqui como habilitá-lo no seu projeto) pode gerar o código para os modelos. Desde a versão 1.0.1 do framework, não é mais necessário que as relações provenham das chaves estrangeiras previamente definidas no banco de dados; é possível defini-las em código, editando o corpo do método relations().

Do código gerado para ambos os modelos (Aluno e Escola, que se encontram na árvore do projeto sob protected/models), destaco os seguintes trechos:

<?php
class Aluno extends CActiveRecord
{

  (...)

	/**
	 * @return array relational rules.
	 */
	public function relations()
	{
		// NOTE: you may need to adjust the relation name and the related
		// class name for the relations automatically generated below.
		return array(
			'escola' => array(self::BELONGS_TO, 'Escola', 'cod_escola'),
		);
	}

  (...)

}
<?php
class Escola extends CActiveRecord
{

  (...)

	/**
	 * @return array relational rules.
	 */
	public function relations()
	{
		// NOTE: you may need to adjust the relation name and the related
		// class name for the relations automatically generated below.
		return array(
			'alunos' => array(self::HAS_MANY, 'Aluno', 'cod_escola'),
		);
	}

  (...)

}

O Gii capturou as definições de chaves estrangeiras e estabeleceu as relações entre as tabelas de acordo com aquelas. No caso, um aluno pertence a (self::BELONGS_TO) uma escola, que, por seu turno, tem vários (self::HAS_MANY) alunos.

A partir disso, abre-se uma miríade de possibilidades. Neste cenário, seria comum ter de apresentar, junto com as informações do aluno, o nome da escola no qual este estuda. Poderíamos escrever o seguinte:

<?php
  // Recupera os dados do aluno cujo código é 1000
  $aluno = Aluno::model()->findByPk(1000);

  echo 'Código: ' . $aluno->cod_aluno . '<br />';
  echo 'Nome do aluno: ' . $aluno->nome_aluno . '<br />';
  echo 'Nome da escola: ' . $aluno->escola->nome_escola . '<br />';

Notem (linha 7) que, para obter o nome da escola, não foi preciso instanciar um objeto da classe Escola apenas para que obtivéssemos o nome da escola. Ao invés disso, beneficiamo-nos de uma relação definida no modelo Aluno.

De forma semelhante, a partir de uma instância da classe Escola, seremos capazes de listar todos os alunos vinculados a ela, escrevendo algo como:

<?php
  // Recupera os dados da escola cujo código é 50
  $escola = Escola::model()->findByPk(50);

  // Recupera uma lista de alunos vinculados à escola
  $alunos = $escola->alunos;

  foreach($alunos as $aluno) {
    echo 'Código: ' . $aluno->cod_aluno . '<br />';
    echo 'Nome do aluno: ' . $aluno->nome_aluno . '<br />';
    echo '<hr />';
  }

O código da linha 6 é o bastante para se obter uma lista de alunos vinculados à escola, graças à relação definida na classe Escola.

Em ambos os exemplos, utilizei a técnica chamada lazy loading para recuperar dados relacionados. Há ainda outras formas de se fazer isso, bem como outros tipos de relações além de self::BELONGS_TO e self::HAS_MANY, sobre as quais você pode obter mais informações consultado o Guia Definitivo do Yii Framework.

Um aspecto final a ser salientado é que estivemos utilizando, durante todo o tempo, um outro padrão de desenvolvimento, denominado Active Record. Ele nos permitiu trabalhar com as informações do banco de dados sem lançar mão, em momento algum, da linguagem SQL. O Active Record, por sua vez, é uma das implementações possíveis de ORM (Object-relational mapping) 8) .

Apresentando o Yii Framework para PHP

Nos últimos quatro anos, trabalhei com o framework PRADO para PHP. Você pode conferir um pouco da minha experiência com ele aqui e ali também.

Quando iniciei com o PRADO, eu era um programador de aplicações desktop, e minha ferramenta predileta era o Borland Delphi Inprise Delphi CodeGear Delphi Embarcadero Delphi. Ao migrar para o ambiente web, a escolha de outra ferramenta que lembrasse o look and feel da antiga foi uma decisão natural, e isso foi-me proporcionado, em boa medida, pelo framework que escolhi.

O PRADO evoluiu, passou da versão 2.x para a 3.x, mas encontrou seu limite, como admitiu seu principal desenvolvedor. A partir do know how adquirido com o desenvolvimento do PRADO, Qiang Xue iniciou um novo framework, com o intuito de reimplementar o que o antecessor tinha de melhor, bem como aproveitar boas ideias introduzidas por outros projetos (veja a seção Credits). Assim vinha a público, em outubro de 2008, a primeira versão do Yii Framework.

Em julho de 2010, o Yii Framework encontra-se na versão 1.1.3, e conta com mais de duas centenas de extensões. Ele implementa rigidamente o padrão de desenvolvimento MVC, algo que o PRADO não fazia muito bem. Desde sempre, o Yii possui uma interface de linha de comando (o yiic), nos moldes do zf do Zend Framework, que automatiza tarefas como criar a estrutura de um projeto, scaffolding (geração de código CRUD), etc. A partir da versão 1.1.2, o framework passou a contar também com uma interface web, chamada Gii, para o scaffolding.

Para demonstrar o poder do Yii Framework, vamos gerar um modelo a partir de uma tabela com a seguinte estrutura:

CREATE TABLE `pessoa` (
  `cod_pessoa` INTEGER(11) NOT NULL AUTO_INCREMENT,
  `nome_pessoa` VARCHAR(100) COLLATE latin1_swedish_ci NOT NULL DEFAULT '',
  `data_nascimento` DATE NOT NULL,
  `sexo` CHAR(1) COLLATE latin1_swedish_ci NOT NULL DEFAULT '',
  PRIMARY KEY (`cod_pessoa`)
)ENGINE=InnoDB
AUTO_INCREMENT=1 CHARACTER SET 'latin1' COLLATE 'latin1_swedish_ci';

Eis o código gerado pelo Gii (ou via yiic shell -> model pessoa), a partir da estrutura acima:

<?php

/**
 * This is the model class for table "pessoa".
 *
 * The followings are the available columns in table 'pessoa':
 * @property integer $cod_pessoa
 * @property string $nome_pessoa
 * @property string $data_nascimento
 * @property string $sexo
 */
class Pessoa extends CActiveRecord
{
	/**
	 * Returns the static model of the specified AR class.
	 * @return Pessoa the static model class
	 */
	public static function model($className=__CLASS__)
	{
		return parent::model($className);
	}

	/**
	 * @return string the associated database table name
	 */
	public function tableName()
	{
		return 'pessoa';
	}

	/**
	 * @return array validation rules for model attributes.
	 */
	public function rules()
	{
		// NOTE: you should only define rules for those attributes that
		// will receive user inputs.
		return array(
			array('nome_pessoa, data_nascimento, sexo', 'required'),
			array('nome_pessoa', 'length', 'max'=>100),
			array('sexo', 'length', 'max'=>1),
			// The following rule is used by search().
			// Please remove those attributes that should not be searched.
			array('cod_pessoa, nome_pessoa, data_nascimento, sexo', 'safe', 'on'=>'search'),
		);
	}

	/**
	 * @return array relational rules.
	 */
	public function relations()
	{
		// NOTE: you may need to adjust the relation name and the related
		// class name for the relations automatically generated below.
		return array(
		);
	}

	/**
	 * @return array customized attribute labels (name=>label)
	 */
	public function attributeLabels()
	{
		return array(
			'cod_pessoa' => 'Cod Pessoa',
			'nome_pessoa' => 'Nome Pessoa',
			'data_nascimento' => 'Data Nascimento',
			'sexo' => 'Sexo',
		);
	}

	/**
	 * Retrieves a list of models based on the current search/filter conditions.
	 * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
	 */
	public function search()
	{
		// Warning: Please modify the following code to remove attributes that
		// should not be searched.

		$criteria=new CDbCriteria;

		$criteria->compare('cod_pessoa',$this->cod_pessoa);

		$criteria->compare('nome_pessoa',$this->nome_pessoa,true);

		$criteria->compare('data_nascimento',$this->data_nascimento,true);

		$criteria->compare('sexo',$this->sexo,true);

		return new CActiveDataProvider(get_class($this), array(
			'criteria'=>$criteria,
		));
	}
}

Como podem perceber, o código gerado para o modelo é bastante completo. O gerador aproveita as configurações existentes no banco de dados para estabelecer regras de validação (veja na função rules()): campos NOT NULL tornam-se atributos requeridos, o comprimento máximo de um atributo do tipo string é o mesmo definido no campo VARCHAR correspondente, etc. Define, inclusive, os rótulos dos atributos a partir dos nomes dos campos (função attributeLabels()), bastando uma pequena edição para que apareçam ao usuário final num português correto.

Meu propósito neste post foi apresentar o Yii Framework e um pouco do seu poder. Se você já conhece ou já trabalha com ele, compartilhe suas impressões nos comentários. Aos demais desenvolvedores PHP, espero ao menos tê-los atiçado a curiosidade e os deixado com água na boca 8) . Para quem deseja se iniciar no framework, recomendo seguir o Tutorial de Criação de um Blog, cujos passos podem ser facilmente adaptados para as necessidades do seu projeto.

Seguir

Obtenha todo post novo entregue na sua caixa de entrada.

%d blogueiros gostam disto: