PageRenderTime 28ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/Library/Kumbia/Controller/StandardForm/StandardFormController.php

http://kumbia-enterprise.googlecode.com/
PHP | 1536 lines | 876 code | 158 blank | 502 comment | 206 complexity | 679018f95a4b4d3d39c69efd09b079ab MD5 | raw file
  1. <?php
  2. /**
  3. * Kumbia Enterprise Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the New BSD License that is bundled
  8. * with this package in the file docs/LICENSE.txt.
  9. *
  10. * If you did not receive a copy of the license and are unable to
  11. * obtain it through the world-wide-web, please send an email
  12. * to license@loudertechnology.com so we can send you a copy immediately.
  13. *
  14. * @category Kumbia
  15. * @package Controller
  16. * @subpackage StandardForm
  17. * @copyright Copyright (c) 2008-2010 Louder Technology COL. (http://www.loudertechnology.com)
  18. * @copyright Copyright (c) 2005-2008 Andres Felipe Gutierrez (gutierrezandresfelipe at gmail.com)
  19. * @license New BSD License
  20. * @version $Id: StandardFormController.php 150 2010-09-24 16:20:10Z gutierrezandresfelipe $
  21. */
  22. /**
  23. * StandardFormController
  24. *
  25. * La Clase StandardForm es la base principal para la generacin de formularios
  26. * de tipo Standard
  27. *
  28. * Notas de Version:
  29. * Desde Kumbia-0.4.7, StandardForm mantiene los valores de la entrada
  30. * cuando los metodos before_ o validation devuelven false;
  31. *
  32. * @category Kumbia
  33. * @package Controller
  34. * @subpackage StandardForm
  35. * @copyright Copyright (c) 2008-2010 Louder Technology COL. (http://www.loudertechnology.com)
  36. * @copyright Copyright (c) 2005-2008 Andres Felipe Gutierrez (gutierrezandresfelipe at gmail.com)
  37. * @license New BSD License
  38. */
  39. abstract class StandardForm extends Controller {
  40. /**
  41. * Tabla con la que trabaja el formulario
  42. *
  43. * @var string
  44. */
  45. protected $source;
  46. /**
  47. * Lista de campos a ignorar en la generacion
  48. *
  49. * @var array
  50. */
  51. protected $ignoreList = array();
  52. /**
  53. * Array que contiene los meta-datos internos
  54. * para generar el formulario
  55. *
  56. * @var string
  57. */
  58. protected $form = array();
  59. /**
  60. * Hace que el formulario no sea persistente
  61. *
  62. * @var boolean
  63. * @staticvar
  64. */
  65. static public $force = false;
  66. /**
  67. * Numero de Minutos que el layout ser? cacheado
  68. *
  69. * @var integer
  70. */
  71. protected $cacheLayout = 0;
  72. /**
  73. * Numero de Minutos que la vista ser? cacheada
  74. *
  75. * @var integer
  76. */
  77. public $cache_view = 0;
  78. /**
  79. * Indica si se deben leer los datos de la base
  80. * de datos para generar el formulario
  81. *
  82. * @var boolean
  83. */
  84. public $scaffold = false;
  85. /**
  86. * Indica el tipo de respuesta que será generado
  87. *
  88. * @var string
  89. */
  90. public $view;
  91. /**
  92. * Indica si se debe mantener los valores del
  93. * formulario o no
  94. *
  95. * @var boolean
  96. */
  97. public $keep_action = true;
  98. /**
  99. * Último fetch realizado en la consulta
  100. *
  101. * @var int
  102. */
  103. private $_lastFetch = 0;
  104. /**
  105. * Mensaje de exito al insertar
  106. *
  107. * @var string
  108. */
  109. public $successInsertMessage = '';
  110. /**
  111. * Mensaje de Fallo al insertar
  112. *
  113. * @var string
  114. */
  115. public $failureInsertMessage = '';
  116. /**
  117. * Mensaje de Suceso al Actualizar
  118. *
  119. * @var string
  120. */
  121. public $successUpdateMessage = "";
  122. /**
  123. * Mensaje de Fallo al Actualizar
  124. *
  125. * @var string
  126. */
  127. public $failureUpdateMessage = "";
  128. /**
  129. * Mensaje de Exito al Borrar
  130. *
  131. * @var string
  132. */
  133. public $successDeleteMessage = "";
  134. /**
  135. * Mensaje de fallo al borrar
  136. *
  137. * @var string
  138. */
  139. public $failureDeleteMessage = "";
  140. /**
  141. * SQL que contiene la ultima consulta efectuada
  142. *
  143. * @var string
  144. */
  145. protected $query;
  146. /**
  147. * Constructor de la clase
  148. *
  149. */
  150. public function __construct(){
  151. $this->setPersistance(true);
  152. if(method_exists($this, 'initialize')){
  153. $this->initialize();
  154. }
  155. }
  156. /**
  157. * Emula la acción Report llamando a show
  158. *
  159. * @access public
  160. */
  161. public function reportAction(){
  162. $this->view = 'index';
  163. $modelName = EntityManager::getEntityName($this->getSource());
  164. if(!EntityManager::isEntity($modelName)){
  165. throw new StandardFormException('No hay un modelo "'.$modelName.'" para hacer la operación de reporte');
  166. return $this->routeTo(array('action' => 'index'));
  167. }
  168. if(!$this->{$modelName}->isDumped()){
  169. $this->{$modelName}->dumpModel();
  170. }
  171. foreach($this->{$modelName}->getAttributesNames() as $field_name){
  172. if(isset($_REQUEST["fl_$field_name"])){
  173. $this->{$modelName}->$field_name = $_REQUEST["fl_$field_name"];
  174. }
  175. }
  176. /**
  177. * Busca si existe un método o un llamado variable al método
  178. * beforeReport, si este método devuelve false termina la ejecución
  179. * de la acción
  180. */
  181. if(method_exists($this, 'beforeReport')){
  182. if($this->beforeReport()===false){
  183. return null;
  184. }
  185. if(Router::getRouted()){
  186. return null;
  187. }
  188. } else {
  189. if(isset($this->beforeReport)){
  190. if($this->{$this->beforeReport}()===false){
  191. return null;
  192. }
  193. if(Router::getRouted()){
  194. return null;
  195. }
  196. }
  197. }
  198. Generator::scaffold($this->form, $this->scaffold);
  199. GeneratorReport::generate($this->form);
  200. /**
  201. * Busca si existe un método o un llamado variable al método
  202. * afterInsert, si este método devuelve false termina la ejecución
  203. * de la acción
  204. */
  205. if(method_exists($this, 'afterReport')){
  206. if($this->afterReport()===false){
  207. return null;
  208. }
  209. if(Router::getRouted()){
  210. return null;
  211. }
  212. } else {
  213. if(isset($this->afterReport)){
  214. if($this->{$this->afterReport}()===false){
  215. return null;
  216. }
  217. if(Router::getRouted()){
  218. return null;
  219. }
  220. }
  221. }
  222. return $this->routeTo(array('action' => 'index'));
  223. }
  224. /**
  225. * Devuelve el source
  226. *
  227. * @return string
  228. */
  229. public function getSource(){
  230. if($this->source==''){
  231. $controller = Router::getController();
  232. ActiveRecordUtils::sqlSanizite($controller);
  233. $this->source = $controller;
  234. }
  235. return $this->source;
  236. }
  237. /**
  238. * Metodo Insert por defecto del Formulario
  239. *
  240. */
  241. public function insertAction(){
  242. $controllerRequest = ControllerRequest::getInstance();
  243. if($controllerRequest->isPost()){
  244. $this->view = 'index';
  245. $this->keep_action = '';
  246. Generator::scaffold($this->form, $this->scaffold);
  247. $modelName = EntityManager::getEntityName($this->getSource());
  248. if(!EntityManager::isEntity($modelName)){
  249. throw new StandardFormException('No hay un modelo "'.$modelName.'" para hacer la operación de inserción');
  250. return $this->routeTo(array('action' => 'index'));
  251. }
  252. if(!$this->{$modelName}->isDumped()){
  253. $this->{$modelName}->dumpModel();
  254. }
  255. foreach($this->{$modelName}->getAttributesNames() as $field_name){
  256. if(isset($_REQUEST["fl_$field_name"])){
  257. $this->{$modelName}->$field_name = $_REQUEST["fl_$field_name"];
  258. }
  259. }
  260. /**
  261. * Busca si existe un método o un llamado variable al método
  262. * validation, si este método devuelve false termina la ejecución
  263. * de la acción
  264. */
  265. if(method_exists($this, 'validation')){
  266. if($this->validation()===false){
  267. $this->keep_action = 'insert';
  268. if(!Router::getRouted()){
  269. return $this->routeTo(array('action' => 'index'));
  270. }
  271. }
  272. if(Router::getRouted()){
  273. return;
  274. }
  275. } else {
  276. if(isset($this->validation)){
  277. if($this->{$this->validation}()===false){
  278. $this->keep_action = 'insert';
  279. if(!Router::getRouted()){
  280. return $this->routeTo(array('action' => 'index'));
  281. }
  282. }
  283. if(Router::getRouted()){
  284. return;
  285. }
  286. }
  287. }
  288. /**
  289. * Busca si existe un método o un llamado variable al método
  290. * beforeInsert, si este método devuelve false termina la ejecucin
  291. * de la acción
  292. */
  293. if(method_exists($this, 'beforeInsert')){
  294. if($this->beforeInsert()===false){
  295. $this->keep_action = 'insert';
  296. if(!Router::getRouted()){
  297. return $this->routeTo(array('action' => 'index'));
  298. }
  299. }
  300. if(Router::getRouted()){
  301. return;
  302. }
  303. } else {
  304. if(isset($this->beforeInsert)){
  305. if($this->{$this->beforeInsert}()===false){
  306. $this->keep_action = 'insert';
  307. if(!Router::getRouted()){
  308. return $this->routeTo(array('action' => 'index'));
  309. }
  310. }
  311. if(Router::getRouted()){
  312. return;
  313. }
  314. }
  315. }
  316. /**
  317. * Subimos los archivos de Imagenes del Formulario
  318. */
  319. foreach($this->form['components'] as $fkey => $rrow){
  320. if($this->form['components'][$fkey]['type']=='image'){
  321. if(isset($_FILES['fl_'.$fkey])){
  322. move_uploaded_file($_FILES['fl_'.$fkey]['tmp_name'], htmlspecialchars('public/img/upload/'.$_FILES['fl_'.$fkey]['name']));
  323. $this->{$modelName}->$fkey = urlencode(htmlspecialchars('upload/'.$_FILES['fl_'.$fkey]['name']));
  324. }
  325. }
  326. }
  327. /**
  328. * Utilizamos el modelo ActiveRecord para insertar el registro
  329. * por lo tanto los
  330. */
  331. $attributes = $this->$modelName->getPrimaryKeyAttributes();
  332. foreach($attributes as $attribute){
  333. if($attribute=='id'){
  334. $this->{$modelName}->id = null;
  335. }
  336. }
  337. if($this->{$modelName}->create()==true){
  338. if($this->successInsertMessage){
  339. Flash::success($this->successInsertMessage);
  340. } else {
  341. Flash::success("Se insertó correctamente el registro");
  342. }
  343. } else {
  344. foreach($this->{$modelName}->getMessages() as $message){
  345. Flash::error($message->getMessage());
  346. }
  347. if(isset($this->failuresInsertMessage)&&$this->failuresInsertMessage!=""){
  348. Flash::error($this->failureInsertMessage);
  349. } else {
  350. Flash::error("Hubo un error al insertar el registro");
  351. $this->keep_action = 'insert';
  352. if(Router::getRouted()==false){
  353. return $this->routeTo(array('action' => 'index'));
  354. }
  355. }
  356. }
  357. foreach($this->{$modelName}->getAttributesNames() as $fieldName){
  358. if(isset($_REQUEST['fl_'.$fieldName])){
  359. $_REQUEST['fl_'.$fieldName] = $this->{$modelName}->readAttribute($fieldName);
  360. }
  361. }
  362. /**
  363. * Busca si existe un método o un llamado variable al método
  364. * after_insert
  365. */
  366. if(method_exists($this, 'afterInsert')){
  367. $this->afterInsert();
  368. if(Router::getRouted()){
  369. return;
  370. }
  371. } else {
  372. if(isset($this->afterInsert)){
  373. $this->{$this->afterInsert}();
  374. }
  375. if(Router::getRouted()){
  376. return;
  377. }
  378. }
  379. } else {
  380. Flash::error('Debe volver a digitar los datos del formulario');
  381. }
  382. // Muestra el Formulario en la accion show
  383. return $this->routeTo(array('action' => 'index'));
  384. }
  385. /**
  386. * Emula la acción Update llamando a show
  387. *
  388. * @access public
  389. */
  390. public function updateAction(){
  391. $this->view = 'index';
  392. $this->keep_action = '';
  393. Generator::scaffold($this->form, $this->scaffold);
  394. $modelName = EntityManager::getEntityName($this->getSource());
  395. if(!EntityManager::isEntity($modelName)){
  396. throw new StandardFormException('No hay un modelo "'.$this->getSource().'" para hacer la operación de actualización');
  397. return $this->routeTo(array('action' => 'index'));
  398. }
  399. if($this->{$modelName}->isDumped()==false){
  400. $this->{$modelName}->dumpModel();
  401. }
  402. /**
  403. * Subimos los archivos de Imágenes del Formulario
  404. */
  405. foreach($this->form['components'] as $fkey => $rrow){
  406. if($this->form['components'][$fkey]['type']=='image'){
  407. if(isset($_FILES['fl_'.$fkey])){
  408. move_uploaded_file($_FILES['fl_'.$fkey]['tmp_name'], htmlspecialchars('public/img/upload/'.$_FILES['fl_'.$fkey]['name']));
  409. $this->{$modelName}->$fkey = urlencode(htmlspecialchars('upload/'.$_FILES['fl_'.$fkey]['name']));
  410. }
  411. }
  412. }
  413. $primaryKey = array();
  414. foreach($this->form['components'] as $fkey => $rrow){
  415. if(isset($rrow['primary'])&&$rrow['primary']==1){
  416. if(isset($_REQUEST["fl_$fkey"])){
  417. $primaryKey[] = "$fkey = '".$_REQUEST["fl_$fkey"]."'";
  418. } else {
  419. Flash::error('Datos incorrectos de actualización');
  420. return $this->routeTo('action: index');
  421. }
  422. }
  423. }
  424. if(count($primaryKey)){
  425. $this->{$modelName}->findFirst(join(' AND ', $primaryKey));
  426. }
  427. foreach($this->{$modelName}->getAttributes() as $fieldName){
  428. if(isset($_REQUEST["fl_$fieldName"])){
  429. $this->{$modelName}->writeAttribute($fieldName, $_REQUEST["fl_$fieldName"]);
  430. }
  431. }
  432. /**
  433. * Busca si existe un método o un llamado variable al método
  434. * validation, si este método devuelve false termina la ejecución
  435. * de la acción
  436. */
  437. if(method_exists($this, 'validation')){
  438. if($this->validation()===false){
  439. $this->keep_action = 'update';
  440. if(!Router::getRouted()){
  441. return $this->routeTo(array('action' => 'index'));
  442. }
  443. }
  444. if(Router::getRouted()){
  445. return;
  446. }
  447. } else {
  448. if(isset($this->validation)){
  449. if($this->{$this->validation}()===false){
  450. $this->keep_action = 'update';
  451. if(!Router::getRouted()){
  452. return $this->routeTo(array('action' => 'index'));
  453. }
  454. }
  455. if(Router::getRouted()){
  456. return;
  457. }
  458. }
  459. }
  460. /**
  461. * Busca si existe un metodo o un llamado variable al metodo
  462. * before_update, si este metodo devuelve false termina la ejecucion
  463. * de la accion
  464. */
  465. if(method_exists($this, 'beforeUdate')){
  466. if($this->beforeUpdate()===false){
  467. $this->keep_action = 'update';
  468. if(!Router::getRouted()){
  469. return $this->routeTo(array('action' => 'index'));
  470. }
  471. }
  472. if(Router::getRouted()){
  473. return null;
  474. }
  475. } else {
  476. if(isset($this->beforeUpdate)){
  477. if($this->{$this->beforeUpdate}()===false){
  478. $this->keep_action = 'update';
  479. if(!Router::getRouted()){
  480. return $this->routeTo(array('action' => 'index'));
  481. }
  482. }
  483. if(Router::getRouted()){
  484. return null;
  485. }
  486. }
  487. }
  488. /**
  489. * Utilizamos el modelo ActiveRecord para actualizar el registro
  490. */
  491. if($this->{$modelName}->update()==true){
  492. if($this->successUpdateMessage){
  493. Flash::success($this->successUpdateMessage);
  494. } else {
  495. Flash::success('Se actualizó correctamente el registro');
  496. }
  497. } else {
  498. $this->keep_action = 'update';
  499. foreach($this->{$modelName}->getMessages() as $message){
  500. Flash::error($message->getMessage());
  501. }
  502. if($this->failureUpdateMessage){
  503. Flash::error($this->failureUpdateMessage);
  504. } else {
  505. Flash::error('Hubo un error al actualizar el registro');
  506. }
  507. $_REQUEST['queryStatus'] = 1;
  508. $_REQUEST['id'] = $this->{$modelName}->readAttribute('id');
  509. return $this->routeTo(array('action' => 'index'));
  510. }
  511. foreach($this->{$modelName}->getAttributes() as $fieldName){
  512. $_REQUEST['fl_'.$fieldName] = $this->{$modelName}->readAttribute($fieldName);
  513. }
  514. /**
  515. * Busca si existe un método o un llamado variable al método
  516. * afterUpdate
  517. */
  518. if(method_exists($this, 'afterUpdate')){
  519. $this->afterUpdate();
  520. if(Router::getRouted()){
  521. return;
  522. }
  523. } else {
  524. if(isset($this->afterUpdate)){
  525. $this->{$this->afterUpdate}();
  526. if(Router::getRouted()){
  527. return;
  528. }
  529. }
  530. }
  531. // Muestra el Formulario en la accion index
  532. return $this->routeTo(array('action' => 'index'));
  533. }
  534. /**
  535. * Esta acción se emplea al generarse un error de validación al actualizar
  536. *
  537. * @access public
  538. */
  539. public function checkAction(){
  540. $_REQUEST['queryStatus'] = true;
  541. }
  542. /**
  543. * Permite mostrar/ocultar los asteriscos al lado
  544. * de los componentes del formulario
  545. *
  546. * @access public
  547. * @param boolean $option
  548. */
  549. public function showNotNulls($option = true){
  550. $this->form['show_not_nulls'] = $option;
  551. }
  552. /**
  553. * Emula la accion Delete llamando a show
  554. *
  555. * @access public
  556. */
  557. public function deleteAction(){
  558. $this->view = 'index';
  559. Generator::scaffold($this->form, $this->scaffold);
  560. $modelName = EntityManager::getEntityName($this->getSource());
  561. if(!EntityManager::isEntity($modelName)){
  562. throw new StandardFormException('No hay un modelo "'.$this->getSource().'" para hacer la operación de actualización');
  563. return $this->routeTo(array('action' => 'index'));
  564. }
  565. if(!$this->{$modelName}->isDumped()){
  566. $this->{$modelName}->dumpModel();
  567. }
  568. foreach($this->{$modelName}->getAttributesNames() as $fieldName){
  569. if(isset($_REQUEST["fl_$fieldName"])){
  570. $this->{$modelName}->$fieldName = $_REQUEST["fl_$fieldName"];
  571. } else {
  572. $this->{$modelName}->$fieldName = "";
  573. }
  574. }
  575. /**
  576. * Busca si existe un método o un llamado variable al método
  577. * before_delete, si este método devuelve false termina la ejecución
  578. * de la acción
  579. */
  580. if(method_exists($this, "beforeDelete")){
  581. if($this->beforeDelete()===false){
  582. if(!Router::getRouted()){
  583. return $this->routeTo(array('action' => 'index'));
  584. }
  585. }
  586. if(Router::getRouted()){
  587. return null;
  588. }
  589. } else {
  590. if(isset($this->beforeDelete)){
  591. if($this->{$this->beforeDelete}()===false){
  592. if(!Router::getRouted()){
  593. return $this->routeTo(array('action' => 'index'));
  594. }
  595. }
  596. if(Router::getRouted()){
  597. return null;
  598. }
  599. }
  600. }
  601. /**
  602. * Utilizamos el modelo ActiveRecord para eliminar el registro
  603. */
  604. if($this->{$modelName}->delete()){
  605. if($this->successDeleteMessage!=''){
  606. Flash::success($this->successDeleteMessage);
  607. } else {
  608. Flash::success("Se eliminó correctamente el registro");
  609. }
  610. } else {
  611. if($this->failureDeleteMessage!=''){
  612. Flash::error($this->failureDeleteMessage);
  613. } else {
  614. Flash::error("Hubo un error al eliminar el registro");
  615. }
  616. }
  617. foreach($this->{$modelName}->getAttributesNames() as $fieldName){
  618. $_REQUEST["fl_$fieldName"] = $this->{$modelName}->readAttribute($fieldName);
  619. }
  620. /**
  621. * Busca si existe un método o un llamado variable al método
  622. * after_delete
  623. */
  624. if(method_exists($this, "afterDelete")){
  625. $this->afterDelete();
  626. if(Router::getRouted()){
  627. return;
  628. }
  629. } else {
  630. if(isset($this->afterDelete)){
  631. $this->{$this->afterDelete}();
  632. if(Router::getRouted()){
  633. return;
  634. }
  635. }
  636. }
  637. // Muestra el Formulario en la accion index
  638. return $this->routeTo(array('action' => 'index'));
  639. }
  640. /**
  641. * Emula la acción Query llamando a show
  642. */
  643. public function queryAction(){
  644. $this->view = 'index';
  645. Generator::scaffold($this->form, $this->scaffold);
  646. $modelName = EntityManager::getEntityName($this->getSource());
  647. if(!EntityManager::isEntity($modelName)){
  648. throw new StandardFormException('No hay un modelo "'.$modelName.'" para hacer la operación de consulta');
  649. return $this->routeTo(array('action' => 'index'));
  650. }
  651. if(isset($this->form['dataFilter'])) {
  652. if($this->form['dataFilter']){
  653. $dataFilter = $form['dataFilter'];
  654. } else {
  655. $dataFilter = "1=1";
  656. }
  657. } else {
  658. $dataFilter = "1=1";
  659. }
  660. if(!isset($this->form['joinTables'])) {
  661. $this->form['joinTables'] = "";
  662. $tables = "";
  663. } else {
  664. if($this->form['joinTables']) {
  665. $tables = ",".$this->form['joinTables'];
  666. } else {
  667. $tables = "";
  668. }
  669. }
  670. if(isset($this->form['joinConditions'])){
  671. $joinConditions = " AND ".$this->form['joinConditions'];
  672. } else {
  673. $joinConditions = '';
  674. }
  675. $modelName = EntityManager::getEntityName($this->getSource());
  676. $model = $this->{$modelName};
  677. if($model->isDumped()==false){
  678. $model->dumpModel();
  679. }
  680. $primaryKeys = $model->getPrimaryKeyAttributes();
  681. $query = "SELECT ".join(',', $primaryKeys)." FROM ".$this->form['source']."$tables WHERE $dataFilter $joinConditions ";
  682. $source = $this->form['source'];
  683. $form = $this->form;
  684. $config = CoreConfig::readEnviroment();
  685. foreach($this->{$modelName}->getAttributesNames() as $fkey){
  686. if(!isset($_REQUEST["fl_".$fkey])){
  687. $_REQUEST["fl_".$fkey] = "";
  688. }
  689. if(trim($_REQUEST["fl_".$fkey])&&$_REQUEST["fl_".$fkey]!='@'){
  690. if(!isset($form['components'][$fkey]['valueType'])){
  691. $form['components'][$fkey]['valueType'] = "";
  692. }
  693. if($form['components'][$fkey]['valueType']=='numeric'||$form['components'][$fkey]['valueType']=='date'){
  694. if($config->database->type!='oracle'){
  695. $query.=" and $source.$fkey = '".$_REQUEST["fl_".$fkey]."'";
  696. } else {
  697. if($form['components'][$fkey]['valueType']=='date'){
  698. $query.=" and $source.$fkey = TO_DATE('".$_REQUEST["fl_".$fkey]."', 'YYYY-MM-DD')";
  699. } else {
  700. $query.=" and $source.$fkey = '".$_REQUEST["fl_".$fkey]."'";
  701. }
  702. }
  703. } else {
  704. if($form['components'][$fkey]['type']=='hidden'){
  705. $query.=" and $source.$fkey = '".$_REQUEST["fl_".$fkey]."'";
  706. } else {
  707. if($form['components'][$fkey]['type']=='check'){
  708. if($_REQUEST["fl_".$fkey]==$form['components'][$fkey]['checkedValue']){
  709. $query.=" and $source.$fkey = '".$_REQUEST["fl_".$fkey]."'";
  710. }
  711. } else {
  712. if($form['components'][$fkey]['type']=='time'){
  713. if($_REQUEST["fl_".$fkey]!='00:00'){
  714. $query.=" and $source.$fkey = '".$_REQUEST["fl_".$fkey]."'";
  715. }
  716. } else {
  717. if(isset($form['components'][$fkey]['primary'])&&$form['components'][$fkey]['primary']){
  718. $query.=" and $source.$fkey = '".$_REQUEST["fl_".$fkey]."'";
  719. } else {
  720. $query.=" and $source.$fkey LIKE '%".$_REQUEST["fl_".$fkey]."%'";
  721. }
  722. }
  723. }
  724. }
  725. }
  726. }
  727. }
  728. $this->query = $query;
  729. $_REQUEST['queryStatus'] = true;
  730. $_REQUEST['id'] = 0;
  731. $this->fetchAction(0);
  732. }
  733. /**
  734. * Emula la acción Fetch llamando a show
  735. *
  736. * @access public
  737. * @param integer $id
  738. */
  739. public function fetchAction($id=0){
  740. $this->view = 'index';
  741. $db = DbBase::rawConnect();
  742. if(!$this->query){
  743. return $this->routeTo(array('action' => 'index'));
  744. }
  745. if($id!=='last'){
  746. $id = $this->filter($id, "int");
  747. if($id==0){
  748. $id = 0;
  749. }
  750. }
  751. $this->_lastFetch = $id;
  752. $db->setFetchMode(DbBase::DB_ASSOC);
  753. $rows = $db->fetchAll($this->query);
  754. if(!isset($id)) {
  755. $id = 0;
  756. } else {
  757. $num = $id;
  758. }
  759. //Hubo resultados en el select?
  760. if(!count($rows)){
  761. Flash::notice("No se encontraron resultados en la búsqueda");
  762. foreach($this->form['components'] as $fkey => $rrow){
  763. unset($_REQUEST["fl_".$fkey]);
  764. }
  765. unset($_REQUEST['queryStatus']);
  766. return $this->routeTo(array('action' => 'index'));
  767. }
  768. if($id>=count($rows)){
  769. $num = count($rows)-1;
  770. }
  771. if($num<0){
  772. $num = 0;
  773. }
  774. if($id==='last'){
  775. $num = count($rows)-1;
  776. }
  777. $_REQUEST['id'] = $num;
  778. /**
  779. * Busca si existe un método o un llamado variable al método
  780. * beforeFetch, si este método devuelve false termina la ejecución
  781. * de la acción
  782. */
  783. if(method_exists($this, 'beforeFetch')){
  784. if($this->beforeFetch()===false){
  785. return null;
  786. }
  787. if(Router::getRouted()){
  788. return null;
  789. }
  790. } else {
  791. if(isset($this->beforeFetch)){
  792. if($this->{$this->beforeFetch}()===false){
  793. return null;
  794. }
  795. if(Router::getRouted()){
  796. return null;
  797. }
  798. }
  799. }
  800. Flash::notice("Visualizando ".($num+1)." de ".count($rows)." registros");
  801. $modelName = EntityManager::getEntityName($this->getSource());
  802. $model = $this->{$modelName};
  803. //especifica el registro que quiero mostrar
  804. $row = $rows[$num];
  805. $conditions = array();
  806. foreach($row as $key => $value){
  807. $conditions[] = $key.' = \''.$value.'\'';
  808. }
  809. $record = $model->findFirst(join(' AND ', $conditions));
  810. foreach($record->getAttributes() as $attribute){
  811. $_REQUEST['fl_'.$attribute] = $record->readAttribute($attribute);
  812. }
  813. $_REQUEST['id'] = $num;
  814. /**
  815. * Busca si existe un método o un llamado variable al métodp afterDelete
  816. */
  817. if(method_exists($this, 'afterFetch')){
  818. $this->afterFetch();
  819. if(Router::getRouted()){
  820. return;
  821. }
  822. } else {
  823. if(isset($this->afterFetch)){
  824. $this->{$this->afterFetch}();
  825. }
  826. if(Router::getRouted()){
  827. return;
  828. }
  829. }
  830. return $this->routeTo(array('action' => 'index'));
  831. }
  832. /**
  833. * Cambia la vista de browse a la vista index
  834. *
  835. * @access public
  836. * @return boolean
  837. */
  838. public function backAction(){
  839. $this->view = 'index';
  840. $this->keep_action = "";
  841. return $this->routeTo(array('action' => 'index'));
  842. }
  843. /**
  844. * Emula la acción Browse llamando a show
  845. *
  846. * @access public
  847. */
  848. public function browseAction(){
  849. $this->view = 'browse';
  850. $this->keep_action = "";
  851. return $this->routeTo(array('action' => 'index'));
  852. }
  853. /**
  854. * Es el metodo principal de StandarForm y es llamado implicitamente
  855. * para mostrar el formulario y su accion asociada.
  856. * La propiedad $this->getSource() indica la tabla con la que se va a generar
  857. * el formulario
  858. *
  859. * @access public
  860. */
  861. public function indexAction(){
  862. if($this->scaffold==true){
  863. $this->form["source"] = $this->getSource();
  864. foreach($this->ignoreList as $ignore){
  865. $this->form['components'][$ignore]['ignore'] = true;
  866. }
  867. Generator::buildForm($this->form, true);
  868. } else {
  869. if(count($this->form)){
  870. $this->form["source"] = $this->getSource();
  871. foreach($this->ignoreList as $ignore){
  872. $this->form['components'][$ignore]['ignore'] = true;
  873. }
  874. Generator::buildForm($this->form);
  875. } else {
  876. throw new StandardFormException('Debe especificar las propiedades del formulario a crear en $this->form ó coloque public $scaffold = true para generar dinámicamente el formulario.');
  877. $this->resetRorm();
  878. }
  879. }
  880. }
  881. /**
  882. * Elimina los meta-datos del formulario
  883. *
  884. * @access public
  885. */
  886. protected function resetForm(){
  887. $appController = $_REQUEST['controller']."Controller";
  888. $instanceName = Core::getInstanceName();
  889. unset($_SESSION['KUMBIA_CONTROLLERS'][$instanceName][$appController]);
  890. }
  891. /**
  892. * Guarda un nuevo valor para una relacion detalle del
  893. * controlador actual
  894. *
  895. * @access public
  896. */
  897. public function _save_helperAction(){
  898. $this->set_response('view');
  899. $db = DbBase::rawConnect();
  900. Generator::scaffold($this->form, $this->scaffold);
  901. $field = $this->form['components'][$this->request('name')];
  902. ActiveRecord::sql_item_sanizite($field['foreignTable']);
  903. ActiveRecord::sql_item_sanizite($field['detailField']);
  904. $db->query("insert into {$field['foreignTable']} ({$field['detailField']})
  905. values ('{$this->request('valor')}')");
  906. }
  907. /**
  908. * Devuelve los valores actualizados de
  909. *
  910. * @access public
  911. */
  912. public function _get_detailAction(){
  913. $this->set_response('xml');
  914. $db = DbBase::rawConnect();
  915. Generator::scaffold($this->form, $this->scaffold);
  916. $name = $this->request('name');
  917. $com = $this->form['components'][$this->request('name')];
  918. if($com['extraTables']){
  919. ActiveRecord::sql_item_sanizite($com['extraTables']);
  920. $com['extraTables']=','.$com['extraTables'];
  921. }
  922. ActiveRecordUtils::sqlSanizite($com['orderBy']);
  923. if(!$com['orderBy']){
  924. $ordb = $name;
  925. } else {
  926. $ordb = $com['orderBy'];
  927. }
  928. if($com['whereCondition']){
  929. $where = 'where '.$com['whereCondition'];
  930. } else {
  931. $where = '';
  932. }
  933. ActiveRecord::sql_item_sanizite($name);
  934. ActiveRecord::sql_item_sanizite($com['detailField']);
  935. ActiveRecord::sql_item_sanizite($com['foreignTable']);
  936. if($com['column_relation']){
  937. $com['column_relation'] = str_replace(";", "", $com['column_relation']);
  938. $query = "select ".$com['foreignTable'].".".$com['column_relation']." as $name,
  939. ".$com['detailField']." from
  940. ".$com['foreignTable'].$com['extraTables']." $where order by $ordb";
  941. $db->query($query);
  942. } else {
  943. $query = "select ".$com['foreignTable'].".$name,
  944. ".$com['detailField']." from ".$com['foreignTable'].$com['extraTables']." $where order by $ordb";
  945. $db->query($query);
  946. }
  947. $xml = new simpleXMLResponse();
  948. while($row = $db->fetchArray()){
  949. if($this->request('valor')==$row[1]){
  950. $xml->add_node(array("value" => $row[0], "text" => $row[1], "selected" => "1"));
  951. } else {
  952. $xml->add_node(array("value" => $row[0], "text" => $row[1], "selected" => "0"));
  953. }
  954. }
  955. $xml->out_response();
  956. }
  957. /**
  958. * Metodo de ayuda para el componente helpText
  959. *
  960. */
  961. public function __autocompleteAction(){
  962. }
  963. /**
  964. * Metodo de ayuda para el componente helpText
  965. *
  966. * @access public
  967. */
  968. public function __check_value_inAction(){
  969. $this->set_response('xml');
  970. $db = DbBase::rawConnect();
  971. $_REQUEST['condition'] = str_replace(";", "", urldecode($_REQUEST['condition']));
  972. ActiveRecord::sql_item_sanizite($_REQUEST['ftable']);
  973. ActiveRecord::sql_item_sanizite($_REQUEST['dfield']);
  974. ActiveRecord::sql_item_sanizite($_REQUEST['name']);
  975. ActiveRecord::sql_item_sanizite($_REQUEST['crelation']);
  976. $_REQUEST['ftable'] = str_replace(";", "", $_REQUEST['ftable']);
  977. $_REQUEST['dfield'] = str_replace(";", "", $_REQUEST['dfield']);
  978. $_REQUEST['name'] = str_replace(";", "", $_REQUEST['name']);
  979. if($_REQUEST["crelation"]){
  980. $db->query("select ".$_REQUEST["dfield"]." from ".$_REQUEST['ftable']. " where ".$_REQUEST['crelation']." = '".$_REQUEST['value']."'");
  981. } else {
  982. $db->query("select ".$_REQUEST["dfield"]." from ".$_REQUEST['ftable']. " where ".$_REQUEST['name']." = '".$_REQUEST['value']."'");
  983. }
  984. echo "<?xml version='1.0' encoding='iso8859-1'?>\r\n<response>\r\n";
  985. $row = $db->fetchArray();
  986. echo "\t<row num='", $db->numRows(), "' detail='", htmlspecialchars($row[0]), "'/>\r\n";
  987. $db->close();
  988. echo "</response>";
  989. }
  990. /**
  991. * Indica que un campo tendró un helper de ayuda
  992. *
  993. * @access public
  994. * @param string $field
  995. * @param string $helper
  996. */
  997. protected function useHelper($field, $helper=''){
  998. if(!$helper){
  999. $helper = $field;
  1000. }
  1001. $this->form['components'][$field."_id"]['use_helper'] = $helper;
  1002. }
  1003. /**
  1004. * Establece el Titulo del Formulario
  1005. *
  1006. * @param string $caption
  1007. */
  1008. protected function setFormCaption($caption){
  1009. $this->form['caption'] = $caption;
  1010. }
  1011. /**
  1012. * Indica que un campo seró de tipo imagen
  1013. *
  1014. * @access public
  1015. * @param string $what
  1016. */
  1017. protected function setTypeImage($what){
  1018. $this->form['components'][$what]['type'] = 'image';
  1019. }
  1020. /**
  1021. * Indica que un campo seró de tipo numerico
  1022. *
  1023. * @access public
  1024. * @param string $what
  1025. */
  1026. protected function setTypeNumeric($what){
  1027. $this->form['components'][$what]['type'] = 'text';
  1028. $this->form['components'][$what]['valueType'] = 'numeric';
  1029. }
  1030. /**
  1031. * Indica que un campo seró de tipo Time
  1032. *
  1033. * @access public
  1034. * @param string $what
  1035. */
  1036. protected function setTypeTime($what){
  1037. $this->form['components'][$what]['type'] = 'time';
  1038. }
  1039. /**
  1040. * Indica que un campo seró de tipo fecha
  1041. *
  1042. * @access public
  1043. * @param string $what
  1044. */
  1045. protected function setTypeDate($what){
  1046. $this->form['components'][$what]['type'] = 'text';
  1047. $this->form['components'][$what]['valueType'] = 'date';
  1048. }
  1049. /**
  1050. * Indica que un campo seró de tipo password
  1051. *
  1052. * @access public
  1053. * @param string $what
  1054. */
  1055. protected function setTypePassword($what){
  1056. $this->form['components'][$what]['type'] = 'password';
  1057. }
  1058. /**
  1059. * Indica que un campo seró de tipo textarea
  1060. *
  1061. * @access public
  1062. * @param string $what
  1063. */
  1064. protected function setTypeTextarea($what){
  1065. $this->form['components'][$what]['type'] = 'textarea';
  1066. }
  1067. /**
  1068. * Indica una lista de campos recibirón entrada solo en mayósculas
  1069. *
  1070. */
  1071. protected function setTextUpper(){
  1072. if(func_num_args()){
  1073. foreach(func_get_args() as $what){
  1074. $this->form['components'][$what]['type'] = 'text';
  1075. $this->form['components'][$what]['valueType'] = 'textUpper';
  1076. }
  1077. }
  1078. }
  1079. /**
  1080. * Crea un combo estótico
  1081. *
  1082. * @param string $what
  1083. * @param string $arr
  1084. */
  1085. protected function setComboStatic($what, $arr){
  1086. $this->form['components'][$what]['type'] = 'combo';
  1087. $this->form['components'][$what]['class'] = 'static';
  1088. $this->form['components'][$what]['items'] = $arr;
  1089. }
  1090. /**
  1091. * Crea un combo Dinamico
  1092. *
  1093. * @access public
  1094. * @param string $what
  1095. */
  1096. protected function setComboDynamic($what){
  1097. $numberArguments = func_num_args();
  1098. $opt = Utils::getParams(func_get_args(), $numberArguments);
  1099. $opt['field'] = $opt['field'] ? $opt['field'] : $opt[0];
  1100. $opt['relation'] = $opt['relation'] ? $opt['relation'] : $opt[1];
  1101. $opt['detail_field'] = $opt['detail_field'] ? $opt['detail_field'] : $opt[2];
  1102. $this->form['components'][$opt['field']]['type'] = 'combo';
  1103. $this->form['components'][$opt['field']]['class'] = 'dynamic';
  1104. $this->form['components'][$opt['field']]['foreignTable'] = $opt['relation'];
  1105. $this->form['components'][$opt['field']]['detailField'] = $opt['detail_field'];
  1106. if(isset($opt['conditions'])&&$opt['conditions']){
  1107. $this->form['components'][$opt['field']]['whereCondition'] = $opt['conditions'];
  1108. }
  1109. if($opt['column_relation']){
  1110. $this->form['components'][$opt['field']]['column_relation'] = $opt['column_relation'];
  1111. }
  1112. if($opt['column_relation']){
  1113. $this->form['components'][$opt['field']]['column_relation'] = $opt['column_relation'];
  1114. } else {
  1115. $this->form['components'][$opt['field']]['column_relation'] = $opt['id'];
  1116. }
  1117. if(isset($opt['force_charset'])){
  1118. $this->form['components'][$opt['field']]['force_charset'] = $opt['force_charset'];
  1119. }
  1120. }
  1121. /**
  1122. * Crea un Texto de Ayuda de Contexto
  1123. *
  1124. * @access public
  1125. * @param string $what
  1126. */
  1127. protected function setHelpContext($what){
  1128. $numberArguments = func_num_args();
  1129. $opt = Utils::getParams(func_get_args(), $numberArguments);
  1130. $field = $opt['field'];
  1131. $this->form['components'][$field]['type'] = 'helpContext';
  1132. }
  1133. /**
  1134. * Especifica que un campo es de tipo E-Mail
  1135. *
  1136. * @access public
  1137. * @param array $fields
  1138. */
  1139. protected function setTypeEmail($fields){
  1140. if(func_num_args()){
  1141. foreach(func_get_args() as $field){
  1142. $this->form['components'][$field]['type'] = 'text';
  1143. $this->form['components'][$field]['valueType'] = "email";
  1144. }
  1145. }
  1146. }
  1147. /**
  1148. * Recibe una lista de campos que no van a ser incluidos en
  1149. * la generación del formulario
  1150. *
  1151. * @access protected
  1152. */
  1153. protected function ignore(){
  1154. if(func_num_args()){
  1155. foreach(func_get_args() as $what){
  1156. $this->form['components'][$what]['ignore'] = true;
  1157. if(!in_array($what, $this->ignoreList)){
  1158. $this->ignoreList[] = $what;
  1159. }
  1160. }
  1161. }
  1162. }
  1163. /**
  1164. * Permite cambiar el tamaóo (size) de un campo $what a $size
  1165. *
  1166. * @access protected
  1167. * @param string $what
  1168. * @param integer $size
  1169. */
  1170. protected function setSize($what, $size){
  1171. $this->form['components'][$what]['attributes']['size'] = $size;
  1172. }
  1173. /**
  1174. * Permite cambiar el tamaóo móximo de caracteres que se puedan
  1175. * digitar en un campo texto
  1176. *
  1177. * @access protected
  1178. * @param string $what
  1179. * @param integer $size
  1180. */
  1181. protected function setMaxlength($what, $size){
  1182. $this->form['components'][$what]['attributes']['maxlength'] = $size;
  1183. }
  1184. /**
  1185. * Hace que un campo aparezca en la pantalla de visualización
  1186. *
  1187. * @access protected
  1188. */
  1189. protected function notBrowse(){
  1190. if(func_num_args()){
  1191. foreach(func_get_args() as $what){
  1192. $this->form['components'][$what]['notBrowse'] = true;
  1193. }
  1194. }
  1195. }
  1196. /**
  1197. * Hace que un campo no aparezca en el reporte PDF
  1198. *
  1199. * @access protected
  1200. * @param string $what
  1201. */
  1202. protected function notReport($what){
  1203. if(func_num_args()){
  1204. foreach(func_get_args() as $what){
  1205. $this->form['components'][$what]['notReport'] = true;
  1206. }
  1207. }
  1208. }
  1209. /**
  1210. * Cambia la imagen del Formulario. $im es una imagen en img/
  1211. *
  1212. * @access protected
  1213. * @param string $im
  1214. */
  1215. protected function setTitleImage($im){
  1216. $this->form['titleImage'] = $im;
  1217. }
  1218. /**
  1219. * Cambia el numero de campos que aparezcan por fila
  1220. * cuando se genere el formulario
  1221. *
  1222. * @access protected
  1223. * @param integer $number
  1224. */
  1225. protected function fieldsPerRow($number){
  1226. $this->form['fieldsPerRow'] = $number;
  1227. }
  1228. /**
  1229. * Inhabilita el formulario para insertar
  1230. *
  1231. * @access protected
  1232. */
  1233. protected function unableInsert(){
  1234. $this->form['unableInsert'] = true;
  1235. }
  1236. /**
  1237. * Inhabilita el formulario para borrar
  1238. *
  1239. * @access protected
  1240. */
  1241. protected function unableDelete(){
  1242. $this->form['unableDelete'] = true;
  1243. }
  1244. /**
  1245. * Inhabilita el formulario para actualizar
  1246. *
  1247. * @access protected
  1248. */
  1249. protected function unableUpdate(){
  1250. $this->form['unableUpdate'] = true;
  1251. }
  1252. /**
  1253. * Inhabilita el formulario para consultar
  1254. *
  1255. * @access protected
  1256. */
  1257. protected function unableQuery(){
  1258. $this->form['unableQuery'] = true;
  1259. }
  1260. /**
  1261. * Inhabilita el formulario para visualizar
  1262. *
  1263. * @access protected
  1264. */
  1265. protected function unableBrowse(){
  1266. $this->form['unableBrowse'] = true;
  1267. }
  1268. /**
  1269. * Inhabilita el formulario para generar reporte
  1270. *
  1271. * @access protected
  1272. */
  1273. protected function unableReport(){
  1274. $this->form['unableReport'] = true;
  1275. }
  1276. /**
  1277. * Indica que un campo seró de tipo Hidden
  1278. *
  1279. * @access protected
  1280. * @param array $fields
  1281. */
  1282. protected function setHidden($fields){
  1283. if(func_num_args()){
  1284. foreach(func_get_args() as $field){
  1285. $this->form['components'][$field]['type'] = 'hidden';
  1286. }
  1287. }
  1288. }
  1289. /**
  1290. * Cambia el Texto Caption de un campo en especial
  1291. *
  1292. * @access protected
  1293. * @param string $fieldName
  1294. * @param string $caption
  1295. */
  1296. protected function setCaption($fieldName, $caption){
  1297. $this->form['components'][$fieldName]['caption'] = $caption;
  1298. }
  1299. /**
  1300. * Hace que un campo sea de solo lectura
  1301. *
  1302. * @access protected
  1303. * @param string $fields
  1304. */
  1305. protected function setQueryOnly($fields){
  1306. if(func_num_args()){
  1307. foreach(func_get_args() as $field){
  1308. $this->form['components'][$field]['queryOnly'] = true;
  1309. }
  1310. }
  1311. }
  1312. /**
  1313. * Cambia el texto de los botones para los formularios
  1314. * estandar setActionCaption('insert', 'Agregar')
  1315. *
  1316. * @access protected
  1317. * @param string $action
  1318. * @param string $caption
  1319. */
  1320. protected function setActionCaption($action, $caption){
  1321. $this->form['buttons'][$action] = $caption;
  1322. }
  1323. /**
  1324. * Asigna un atributo a un campo del formulario
  1325. * setAttribute('campo', 'rows', 'valor')
  1326. *
  1327. * @access protected
  1328. * @param string $field
  1329. * @param string $name
  1330. * @param mixed $value
  1331. */
  1332. protected function setAttribute($field, $name, $value){
  1333. $this->form['components'][$field]['attributes'][$name] = $value;
  1334. }
  1335. /**
  1336. * Asigna un atributo a un campo del formulario
  1337. * setAttribute('campo', 'rows', 'valor')
  1338. *
  1339. * @access protected
  1340. * @param string $field
  1341. * @param string $event
  1342. * @param string $value
  1343. */
  1344. protected function setEvent($field, $event, $value){
  1345. $this->form['components'][$field]['attributes']["on".$event] = $value;
  1346. }
  1347. /**
  1348. * Ejecuta el inicializador para tomar los cambios sin reiniciar el navegador
  1349. *
  1350. * @access public
  1351. */
  1352. public function __wakeup(){
  1353. if(method_exists($this, "initialize")){
  1354. $this->initialize();
  1355. }
  1356. $this->setPersistance(true);
  1357. parent::__wakeup();
  1358. }
  1359. /**
  1360. * Trata de recuperarse de errores ocurridos en la base de datos
  1361. *
  1362. * @access public
  1363. * @param Exception $e
  1364. */
  1365. public function onException($e){
  1366. if(is_subclass_of($e, 'DbException')){
  1367. if($e instanceof DbConstraintViolationException){
  1368. Flash::error('No se puede efectuar la operación ya que el registro se esta usando en otras partes del sistema');
  1369. $action = Router::getAction();
  1370. $this->RouteTo('action: index');
  1371. } else {
  1372. throw $e;
  1373. }
  1374. } else {
  1375. throw $e;
  1376. }
  1377. }
  1378. }