Michael Mafort

CakePHP

Facilidades para sua vida – Parte 8 – Cronjobs com cakephp

by Michael Mafort on fev.26, 2009, under CakePHP, Facilidades para sua vida, Linux, PHP

Bom pessoal, de volta a ativa, vou neste post falar um pouco sobre como utilizar tarefas agendadas utilizando o crontab do linux.

Primeiro passo, copie o arquivo webroot/index.php para cron_dispatcher.php.

No cakephp versão final 1.2.1.8004, a linha a ser editada é após a 83, que está o seguinte código:

1
2
3
if (!include(CORE_PATH . 'cake' . DS . 'bootstrap.php')) {
		trigger_error("CakePHP core could not be found.  Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php.  It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR);
	}

Você irá substituir para:

1
2
3
4
5
6
7
8
9
10
if (!include(CORE_PATH . 'cake' . DS . 'bootstrap.php')) {
		trigger_error("CakePHP core could not be found.  Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php.  It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR);
	}
else {
    define(‘CRON_DISPATCHER’, true);
    if($argc == 2) {
        $Dispatcher = new Dispatcher();
        $Dispatcher -> dispatch($argv[1]);
    }
 }

Assim seu script dará acesso ao seu controller através do dispatcher, utilizando o phpclient. Para executar o script utilizando o crontab, deve-se fazer o seguinte:

1
* * * * * php -q /var/www/app/webroot/cron_dispatcher.php /products/cron/

Onde os asteriscos na ordem significam:
1 – Minuto (0-59)
2 – Hora (0-23)
3 – Dia (1-31)
4 – Mês (1-12)
5 – Semana (0-6)

Para que os valores repitam sempre utilize o mesmo asterisco, exemplo: para executar o script 1 vez por dia a 0h use:

1
0 0 * * * php -q /var/www/app/webroot/cron_dispatcher.php /products/cron/

“php -q” executa o arquivo passado a seguir como parametro. neste exemplo vai chamar o arquivo /var/www/app/webroot/cron_dispatcher.php (lembre de passar o caminho absoluto ao arquivo).
O parametro /products/cron/ diz que o seu dispatcher vai chamar o action cron do controller products.

Agora já esta pronto o seu crontab, é só rodar e testar.

Abraço!

1 Comment more...

Facilidades para sua vida – Parte 7 – CakePHP json encode

by Michael Mafort on fev.02, 2009, under CakePHP, Facilidades para sua vida, PHP

Bom nesta parte vamos tratar de um problema muito comum quando vamos trabalhar com ajax, utilizando json como padrão de dados. O principal problema que enfrentamos é referente ao uso de palavras acentuadas e configurações do servidor, então para livrar deste problema criei um component que transforma as informações de uma query em json.

jsonComponent.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class jsonComponent extends Object {
 
	public function encode($data){
		$tmp_arr = array();
		if( is_array($data) ){
			foreach( $data as $key => $value ){
				if( is_array($value) ){
					$tmp_arr[] = "'$key':{" . $this->encode($value) . "}";
				}
				else{
					$tmp_arr[] = "'$key':'$value'";
				}
			}
		}
		else
		{
			return "'$data'";
		}
		return join(", ", $tmp_arr);
	}
 
}

Para utilizá-lo basta inserir em seu controller a variável:

1
2
3
4
5
6
7
8
9
10
11
12
13
$components = array('json');
 
//para converter um array em json use:
 
function minha_funcao(){
    $produtos = array('Produto'=>array( array('id'=>1, 'descricao'=> 'Carne moída', 'valor'=>10.50), array('id'=>2, 'descricao'=>'Feijão preto', 'valor'=>2.90)));
 
    $json = "{" . $this->json->encode($produtos) . "}";
 
    echo $json;
 
    //resultado será:
    //{'Produto':{'0':{'id':'1', 'descricao':'Carne moída', 'valor':'10.5'}, '1':{'id':'2', 'descricao':'Feijão preto', 'valor':'2.9'}}}

Ou você poderá criar diretamente um novo método ao seu app_model da seguinte forma:
app_model.php

1
2
3
4
5
6
7
8
        public function json($type='all', $conditions=array()){
		$result = $this->find($type, $conditions);
 
		App::import("Component", "json");
		$json = new jsonComponent();
 
		return "{". $json->encode($result) ."}";
	}

Com o método no app_model, você vai chamar o seu método da seguinte forma:

1
2
3
4
5
6
7
8
9
//Utilize a mesma sintaxe do find
$meu_json = $this->MeuModel->json('all', array('conditions'=>array('MeuModel.preco < 2'), 'fields'=>array('MeuModel.id','MeuModel.descricao')));
 
echo $meu_json;//{'Produto':{'0':{'id':'1', 'descricao':'Carne moída', 'valor':'10.5'}, '1':{'id':'2', 'descricao':'Feijão preto', 'valor':'2.9'}}}
 
//Lembre-se sempre de definir o header antes da saída de dados "echo" quando estiver utilizando json.
//Exemplo:
header('Content-Type: text/javascript');
echo $meu_json;

No javascript para acessar os valores pode-se usar:

1
2
3
var json = {'Produto':{'0':{'id':'1', 'descricao':'Carne moída', 'valor':'10.5'}, '1':{'id':'2', 'descricao':'Feijão preto', 'valor':'2.9'}}};
 
produto_um = json.Produto[0].id; // use um loop para percorrer dinamicamente todo o objeto, recomendo utilizar "for in".

Bom espero que possa ser mais uma facilidade para vocês também.

Abraço!

Leave a Comment more...

Facilidades para sua vida – Parte 3 – Utilizando frameworks

by Michael Mafort on jan.25, 2009, under CakePHP, Facilidades para sua vida, PHP

Framework segundo a wikipédia, é “um conjunto de classes que colaboram para realizar uma responsabilidade para um domínio de um subsistema da aplicação.”

Resumindo os frameworks vieram para facilitar nossas vidas, agilizando (e muito) o processo de desenvolvimento e criando padrões que tornam a programação unificada e de fácil manutenção por qualquer um, desde que o padrão adotado pelo framework seja entendido e aplicado pelo desenvolvedor.

Alguns exemplos de frameworks:

Javascript (Biblioteca de funções javascript, como efeitos, animações, controle DOM, ajax…):

Jquery – Na minha opinião a mais produtiva e fácil aprendizado, compatibilidade com a maioria dos browsers em uso e vários plugins que podem ser acrescidos para facilitar ainda mais.
Prototype – Fácil uso de ajax e controle DOM.
ExtJS – Com uma biblioteca gráfica para customização muito boa.
Dojo, – Rápida e com vários addons.

PHP:

CakePHP - Agilidade no desenvolvimento, padrões de Design Pattern, MVC,  ORM  (Mapeamento Objeto Relacional), Scaffold (Desenvolvimento de Criação, Edição, Visualização e Exclusão de dados em uma linha de código), acesso a components entre outras milhares de funcionalidades que facilitam nossas vidas. Baseado no Rails do Ruby on Rails, é um framework php completo.
CodeIgniter - MVC, curva de aprendizagem baixa, fácil intendimento, processamento veloz das informações documentação completa.
ZendFramework - O mais robusto e com certeza o que será em breve o melhor framework, pois é desenvolvido pela mesma empresa que mantem hoje o php.

Bom acredito que com estes frameworks já possa ter um desempenho melhor e uma programação mais limpa daqui pra frente.

Abraço.

1 Comment more...

CakePHP LogsBehavior

by Michael Mafort on jan.18, 2009, under CakePHP

Bom seguindo uma necessidade de registrar log de tudo que é feito em uma aplicação eu desenvolvi um behavior para ser usado no cakephp, muito simples e prático. Ele registra alterações nas tabelas como insert, update e delete.

Update -> Grava o registro antigo e o novo.
Insert -> Grava o novo registro.
Delete -> Grava o registro antigo.

Em todos os logs são gravados o id do usuário logado que fez a alteração, a data da alteração, o nome do model que foi alterado e a ação que foi efetuada (add, edit ou delete)

A unica parte  que deverá ser editada de acordo com seu sistema de autenticação é o relacionamento com o model que está utilizando na autenticação.

Vamos ao que interessa então:

Criando a tabela no banco de dados, estou utilizando o mysql.

1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE TABLE `logs` (
 
          `id` int(10) unsigned NOT NULL auto_increment,
          #este é o meu id do usuario logado, meu model de autenticação chama-se authuser
          `authuser_id` int(10) unsigned NOT NULL,
          `model` varchar(60) default NULL,
          `action` varchar(20) default NULL,
          `old_data` text,
          `new_data` text,
          `created` datetime default NULL,
          PRIMARY KEY  (`id`),
          KEY `logs_FKIndex1` (`authuser_id`)
        ) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Crie o log model models/log.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Log extends AppModel {
 
	var $name = 'Log';
 
	//The Associations below have been created with all possible keys, those that are not needed can be removed
	var $belongsTo = array(
	      'Authuser' => array('className' => 'Authuser',
			'foreignKey' => 'authuser_id',
			'conditions' => '',
			'fields' => '',
			'order' => ''
		)
	);
 
}

Criando agora o behavior log: models/behaviors/logs.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
 
/**
 * Behavior for log actions of tables.
 *
 * Behavior to simplify logs
 *
 * PHP versions 5
 *
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @filesource
 * @copyright	Copyright 2005-2008, Criasol Ltd.
 * @link		http://www.criasol.com.br
 * @since		12-07-2009
 * @license		http://www.opensource.org/licenses/mit-license.php The MIT License
 */
 
/**
 * Behavior to register log to all actions in your table model
 *
 */
 
App::import('Model','Log');
App::import('Component', 'Session');
 
class LogsBehavior extends ModelBehavior {
 
/**
 * Current model
 *
 * @var Object
 */
private $Model;
 
/**
 * Session component object
 *
 * @var Object
 */
private $Session;
 
/**
 * Old data
 * last data from model before modified
 *
 * @var array
 */
private $_oldData;
 
/**
 * New data
 * new value from model after modified
 *
 * @var array
 */
private $_newData;
 
/**
 * Model log
 *
 * @var Object
 */
private $Log;
 
/**
 * Action
 * type of action called
 *
 * @var string
 */
private $_action;
 
/**
 * Deleted id
 * id from data to delete
 *
 * @var int
 */
private $_deletedId;
 
/**
 * Setup method
 *
 * Configure this behavior
 *
 * @param ObjectModel $model
 * @param array $config
 */
public function setup(&$model, $config = null){
	$this->Model = $model;
	$this->Session = new SessionComponent();
	$this->Log = new Log();
}
 
/**
 * Before save
 *
 * @param ObjectModel $model
 * @return boolean true
 */
public function beforeSave(&$model){
	if( is_numeric($this->Model->id) ){
		$this->_action = 'edit';
		$newData = $this->Model->find('first', array('conditions'=> array( "{$this->Model->name}.id" => $this->Model->data[$this->Model->name]['id'] ) ) );
 
		foreach( $newData[$this->Model->name] as $input => $value ){
			$this->_oldData .= "$input :: $valuen";
		}
 
	}
	else
		$this->_action = 'add';
 
	return true;
}
 
/**
 * After save
 *
 * @param objectModel $model
 * @param string $created
 * @return boolean true
 */
public function afterSave(&$model, $created){
	$newData = $this->Model->read(null, $this->Model->id);
	foreach( $newData[$this->Model->name] as $input => $value ){
		$this->_newData .= "$input :: $valuen";
	}
	$this->write();
	return true;
}
 
/**
 * Before delete
 *
 * @param objectModel $model
 * @param boolean $cascade
 * @return boolean true
 */
public function beforeDelete(&$model, $cascade=true){
 
	$this->_action = 'delete';
	$this->_deletedId = $this->Model->data[$this->Model->name]['id'];
	$newData = $this->Model->read(null, $this->_deletedId );
 
	foreach( $newData[$this->Model->name] as $input => $value ){
		$this->_oldData .= "$input :: $valuen";
	}
 
	return true;
}
 
/**
 * After delete action
 *
 * @param ObjectModel $model
 * @return boolean true
 */
public function afterDelete(&$model){
	$this->write();
	return true;
}
 
/**
 * Write log
 *
 * @return void
 */
public function write(){
	if( $this->Model->name == 'Log' )
		return true;
 
	$this->Log->id = null;
	$this->Log->save(array(
		'Log'=>array(
			'authuser_id' => $this->Session->read('Authuser.id'),
			'model' => $this->Model->name,
			'action' => $this->_action,
			'old_data' => $this->_oldData,
			'new_data' => $this->_newData
			)
		));
	}
 
}
?>

Na linha 183 edite o valor de session read para o valor do id do seu usuário logado.

Para funcionar com php 4, retire os public’s e private’s  do código, em functions deixe vazio nas variáveis substitua por var.

Agora para salvar os logs basta inserir em seu model que deseja salvar os logs a variável:

public $actsAs = array(’Logs’);

Por hoje é só…

Abraços,

3 Comments more...

Procurando por algo?

Digita ai pra ver se encontramos:

Não achou o que procurava? Envie um comentário para o autor informando o que deseja!