Olá, sou novo por aqui e tenho uma idéia a compartilhar. Mais que expor, gostaria da opinião dos colegas mais experientes. Quem sabe um bug ou melhoria nas entrelinhas (nomenclatura tb hihi - qual nome dar?). Ficarei honrado pelo feedback!
Recentemente chegado ao Yii, utilizei-o agora (pela primeira vez) para criar um backend de apoio a um website corporativo. Toda uma estrutura já existia, porém eu quis utilizar a plataforma para as novas funcionalidade porque o modelo atual simplesmente me dá nos nervos.
Surgiu então um problema, ao implementar a funcionalidade no website: deveria eu me esquecer de todas as regras e estruturas já criadas no Yii e voltar ao plain old PHP e mysql_query ou deveria tentar pelo menos colher os dados no Yii.
A questão foi simples de ser respondida…
Após pesquisar um pouco percebi que o Yii, aparentemente, não pode ser incluído em outra aplicação, como por exemplo o WordPress pode
Ah, muito triste pra mim! Mas não me deixei abater e logo uma idéia surgiu: Bem, um WebService pode colher os dados.
Putz, implementar todas as variantes de consultas num webservice vai dar um trabalho (não conheço a solução do Yii - perdi algo?) então eu precisava de algo mais simplificado.
Foi aí que a idéia tomou forma (ufa, que estoria) e eu escolhi que assim fosse. Bem, vocês podem estar se perguntando o porque desse lenga-lenga. E eu respondo: é um metódo não muito convencional - muitos facilmente o condenariam ( eval( $snippet ) ).
Mas o fato é que esta aí! Quem quiser compartilhar sua opinião por favor a faça, pois em breve vou finalizar os detalhes e disponibilizar a extensão no repositório oficial.
Obrigado pela paciencia
Por enquanto a estrutura está assim:
1. Insira em protected/controller/ExecuteController.php
<?php
//TODO: Nomear, comentar e fazer disto uma extension
class ExecuteController extends Controller {
private $token = 'AbobrinhaComFeijão';
public function actionIndex()
{
//$this->_return($_POST);
if ( strcmp($_POST['token'], $this->token) == 0 )
$this->_return( $this->_execute( $_POST['snippet'] ) );
else
$this->_return( array('error'=>"Not Allowed") );
}
function _execute( $snippet ) {
$result = eval( $snippet );
if ( is_null($result) )
$result = array('error'=>'No return defined or no data');
if ( $result === false )
$result = array('error'=>'Execution error');
return $result;
}
function _return( $object ) {
echo CJSON::encode( $object );
Yii::app()->end();
}
function actionTeste() {
//Use this to test your snippets directly on browser
$this->_return(
UsuarioPlano::consomeAnuncio('686')
);
}
}
?>
2. Fora do Yiiadicione o arquivo a seguir. Ele é o "chamador" do Yii. /includes/yii.caller.php
ps. Configure o caminho da aplicação no constructor
<?php
/**
* by thiago@internetbudi.com.br
* class Yii
* Metodo "diferente" para requisitar dados da apĺicação no yii framework
* Uma especie de webservice, ele requisita uma determinada ação na aplicação
* que faz um evaluation de um código e retorna seu objeto correspondente.
*
* Idicado para transitar ActiveRecord, mas retorna com sucesso qualquer tipo de objeto serializavel em JSON
* @todo Verificar sanidade do metódo. kinda crazy
*/
class Yii {
private $token = 'AbobrinhaComFeijão'; //use um gerador randomico!
private $yiiIndex, $yiiUri;
function Yii() {
$this->yiiIndex = "http://$_SERVER[HTTP_HOST]/yii/index.php";
$this->setAction('execute');
}
function execute( $snippet ) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->yiiUri);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, array( 'snippet'=>$snippet, 'token'=>$this->token ));
//return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// $response contains the output string
$response = curl_exec($ch);
curl_close($ch);
//OPTIONAL
$response = utf8_decode($response);
/* echo ">> $this->yiiUri $response";
exit; */
return json_decode($response, true);
}
function setAction( $action ) {
$this->yiiUri = "$this->yiiIndex?r=$action";
}
function retrieve( $call ) {
return $this->execute( "return $call;" );
}
}
?>
3. Agora basta a gente trabalhar com esta classe, mais ou menos assim:
require_once("/includes/yii.caller.php");
$app = new Yii;
print_r( $app->retrieve->( 'array("retorno"=>"Isto foi executado no Yii version". Yii::getVersion() )' );
$snippet = '$produtos = Produtos::model()->findAll();
return $produtos;';
print_r( $app->execute( $snippet ) )