]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - data/BeanFactory.php
Release 6.5.3
[Github/sugarcrm.git] / data / BeanFactory.php
1 <?php
2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3 /*********************************************************************************
4  * SugarCRM Community Edition is a customer relationship management program developed by
5  * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc.
6  * 
7  * This program is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU Affero General Public License version 3 as published by the
9  * Free Software Foundation with the addition of the following permission added
10  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13  * 
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
17  * details.
18  * 
19  * You should have received a copy of the GNU Affero General Public License along with
20  * this program; if not, see http://www.gnu.org/licenses or write to the Free
21  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  * 02110-1301 USA.
23  * 
24  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
26  * 
27  * The interactive user interfaces in modified source and object code versions
28  * of this program must display Appropriate Legal Notices, as required under
29  * Section 5 of the GNU Affero General Public License version 3.
30  * 
31  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32  * these Appropriate Legal Notices must retain the display of the "Powered by
33  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34  * technical reasons, the Appropriate Legal Notices must display the words
35  * "Powered by SugarCRM".
36  ********************************************************************************/
37
38
39 require_once('data/SugarBean.php');
40
41 /**
42  * Factory to create SugarBeans
43  * @api
44  */
45 class BeanFactory {
46     protected static $loadedBeans = array();
47     protected static $maxLoaded = 10;
48     protected static $total = 0;
49     protected static $loadOrder = array();
50     protected static $touched = array();
51     public static $hits = 0;
52
53     /**
54      * Returns a SugarBean object by id. The Last 10 loaded beans are cached in memory to prevent multiple retrieves per request.
55      * If no id is passed, a new bean is created.
56      * @static
57      * @param String $module
58      * @param String $id
59      * @param Array $params A name/value array of parameters. Names: encode, deleted, 
60      *        If $params is boolean we revert to the old arguments (encode, deleted), and use $params as $encode.
61      *        This will be changed to using only $params in later versions.
62      * @param Bool $deleted @see SugarBean::retrieve
63      * @return SugarBean
64      */
65     public static function getBean($module, $id = null, $params = array(), $deleted = true)
66     {
67         
68         // Check if params is an array, if not use old arguments
69         if (isset($params) && !is_array($params)) {
70                 $params = array('encode' => $params);
71         }
72         
73         // Pull values from $params array
74         $encode = isset($params['encode']) ? $params['encode'] : true;
75         $deleted = isset($params['deleted']) ? $params['deleted'] : $deleted;
76         
77         if (!isset(self::$loadedBeans[$module])) {
78             self::$loadedBeans[$module] = array();
79             self::$touched[$module] = array();
80         }
81
82         $beanClass = self::getBeanName($module);
83
84         if (empty($beanClass) || !class_exists($beanClass)) return false;
85
86         if (!empty($id))
87         {
88             if (empty(self::$loadedBeans[$module][$id]))
89             {
90                 $bean = new $beanClass();
91                 $result = $bean->retrieve($id, $encode, $deleted);
92                 if($result == null)
93                     return FALSE;
94                 else
95                     self::registerBean($module, $bean, $id);
96             } else
97             {
98                 self::$hits++;
99                 self::$touched[$module][$id]++;
100                 $bean = self::$loadedBeans[$module][$id];
101             }
102         } else {
103             $bean = new $beanClass();
104         }
105
106         return $bean;
107     }
108
109     public static function newBean($module)
110     {
111         return self::getBean($module);
112     }
113
114     public static function getBeanName($module)
115     {
116         global $beanList;
117         if (empty($beanList[$module]))  return false;
118
119         return $beanList[$module];
120     }
121
122     /**
123      * Returns the object name / dictionary key for a given module. This should normally
124      * be the same as the bean name, but may not for special case modules (ex. Case vs aCase)
125      * @static
126      * @param String $module
127      * @return bool
128      */
129     public static function getObjectName($module)
130     {
131         global $objectList;
132         if (empty($objectList[$module]))
133             return self::getBeanName($module);
134
135         return $objectList[$module];
136     }
137
138
139     /**
140      * @static
141      * This function registers a bean with the bean factory so that it can be access from accross the code without doing
142      * multiple retrieves. Beans should be registered as soon as they have an id.
143      * @param String $module
144      * @param SugarBean $bean
145      * @param bool|String $id
146      * @return bool true if the bean registered successfully.
147      */
148     public static function registerBean($module, $bean, $id=false)
149     {
150         global $beanList;
151         if (empty($beanList[$module]))  return false;
152
153         if (!isset(self::$loadedBeans[$module]))
154             self::$loadedBeans[$module] = array();
155
156         //Do not double register a bean
157         if (!empty($id) && isset(self::$loadedBeans[$module][$id]))
158             return true;
159
160         $index = "i" . (self::$total % self::$maxLoaded);
161         //We should only hold a limited number of beans in memory at a time.
162         //Once we have the max, unload the oldest bean.
163         if (count(self::$loadOrder) >= self::$maxLoaded - 1)
164         {
165             for($i = 0; $i < self::$maxLoaded; $i++)
166             {
167                 if (isset(self::$loadOrder[$index]))
168                 {
169                     $info = self::$loadOrder[$index];
170                     //If a bean isn't in the database yet, we need to hold onto it.
171                     if (!empty(self::$loadedBeans[$info['module']][$info['id']]->in_save))
172                     {
173                         self::$total++;
174                     }
175                     //Beans that have been used recently should be held in memory if possible
176                     else if (!empty(self::$touched[$info['module']][$info['id']]) && self::$touched[$info['module']][$info['id']] > 0)
177                     {
178                         self::$touched[$info['module']][$info['id']]--;
179                         self::$total++;
180                     }
181                     else
182                         break;
183                 } else {
184                     break;
185                 }
186                 $index = "i" . (self::$total % self::$maxLoaded);
187             }
188             if (isset(self::$loadOrder[$index]))
189             {
190                 unset(self::$loadedBeans[$info['module']][$info['id']]);
191                 unset(self::$touched[$info['module']][$info['id']]);
192                 unset(self::$loadOrder[$index]);
193             }
194         }
195
196         if(!empty($bean->id))
197            $id = $bean->id;
198
199         if ($id)
200         {
201             self::$loadedBeans[$module][$id] = $bean;
202             self::$total++;
203             self::$loadOrder[$index] = array("module" => $module, "id" => $id);
204             self::$touched[$module][$id] = 0;
205         } else{
206             return false;
207         }
208         return true;
209     }
210 }
211