1: <?php
2:
3: App::uses('AppModel', 'Model');
4:
5: abstract class ExtendedHasManyAppModel extends AppModel {
6:
7: private $_saveParent = false;
8: public $virtualFieldsSchema;
9:
10: public function __construct($id = false, $table = null, $ds = null, $hasManyUtilsAssociation = false) {
11: parent::__construct($id, $table, $ds);
12: if ($hasManyUtilsAssociation === false) {
13: $hasManyUtilsAssociation = array_keys($this->hasMany);
14: }
15: $this->Behaviors->load('Base.HasManyUtils', array(
16: 'associations' => $hasManyUtilsAssociation
17: ));
18: }
19:
20: public function save($data = null, $validate = true, $fieldList = array()) {
21: if ($this->_saveParent) {
22: return parent::save($data, $validate, $fieldList);
23: } else {
24: $options = compact('validate', 'fieldList');
25: $this->_saveParent = true;
26: $result = $this->saveAll($data, $options);
27: $this->_saveParent = false;
28: return $result;
29: }
30: }
31:
32: public function saveAll($data = null, $options = array()) {
33: if (!empty($options['selfOnly'])) {
34: return parent::save($data);
35: }
36: $this->begin();
37: $this->set($data);
38: $options['atomic'] = false;
39: if (!$this->beforeSaveAll($options)) {
40: return false;
41: }
42: $created = $this->id === false;
43: $result = $this->_evaluateSaveAllResult($this->_parentSaveAll(null, $options));
44: if ($result) {
45: $this->commit();
46: $this->afterSaveAll($created, $options);
47: } else {
48: $this->rollback();
49: }
50: return $result;
51: }
52:
53: protected function beforeSaveAll($options) {
54: return true;
55: }
56:
57: protected function afterSaveAll($created, $options) {
58:
59: }
60:
61: public function _parentSaveAll($data = null, $options = array()) {
62: if ($this->Behaviors->enabled('HasManyUtils')) {
63: $this->set($data);
64: if (!$this->_triggerOptionalBehaviorCallback('beforeSaveAll', $options)) {
65: return false;
66: }
67: $created = parent::saveAll($this->data, $options);
68: $this->_triggerOptionalBehaviorCallback('afterSaveAll', $created);
69:
70: return $created;
71: } else {
72: return parent::saveAll($data, $options);
73: }
74: }
75:
76: private function _triggerOptionalBehaviorCallback($callback, $parameter) {
77: $result = true;
78: foreach ($this->Behaviors->enabled() as $behavior) {
79: if (method_exists($this->Behaviors->{$behavior}, $callback)) {
80: if (!call_user_func(array($this->Behaviors->{$behavior}, $callback), $this, $parameter)) {
81: $result = false;
82: }
83: }
84: }
85: return $result;
86: }
87:
88: private function _evaluateSaveAllResult($saveAllResult) {
89: if ($saveAllResult === true) {
90: return true;
91: } else if ($saveAllResult === false) {
92: return false;
93: } else if (is_array($saveAllResult)) {
94: foreach ($saveAllResult as $individualResult) {
95: if (!$this->_evaluateSaveAllResult($individualResult)) {
96: return false;
97: }
98: }
99: return true;
100: } else {
101: throw new Exception("Valor não mapeado para \$saveAllResult = '$saveAllResult'");
102: }
103: }
104:
105: }
106: