]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - data/BeanFactory.php
Release 6.4.0
[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-2011 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      * @return SugarBean
60      */
61     public static function getBean($module, $id = null)
62     {
63         if (!isset(self::$loadedBeans[$module])) {
64             self::$loadedBeans[$module] = array();
65             self::$touched[$module] = array();
66         }
67
68         $beanClass = self::getBeanName($module);
69
70         if (empty($beanClass) || !class_exists($beanClass)) return false;
71
72         if (!empty($id))
73         {
74             if (empty(self::$loadedBeans[$module][$id]))
75             {
76                 $bean = new $beanClass();
77                 $result = $bean->retrieve($id);
78                 if($result == null)
79                     return FALSE;
80                 else
81                     self::registerBean($module, $bean, $id);
82             } else
83             {
84                 self::$hits++;
85                 self::$touched[$module][$id]++;
86                 $bean = self::$loadedBeans[$module][$id];
87             }
88         } else {
89             $bean = new $beanClass();
90         }
91
92         return $bean;
93     }
94
95     public static function newBean($module)
96     {
97         return self::getBean($module);
98     }
99
100     public static function getBeanName($module)
101     {
102         global $beanList;
103         if (empty($beanList[$module]))  return false;
104
105         return $beanList[$module];
106     }
107
108     /**
109      * Returns the object name / dictionary key for a given module. This should normally
110      * be the same as the bean name, but may not for special case modules (ex. Case vs aCase)
111      * @static
112      * @param String $module
113      * @return bool
114      */
115     public static function getObjectName($module)
116     {
117         global $objectList;
118         if (empty($objectList[$module]))
119             return self::getBeanName($module);
120
121         return $objectList[$module];
122     }
123
124
125     /**
126      * @static
127      * This function registers a bean with the bean factory so that it can be access from accross the code without doing
128      * multiple retrieves. Beans should be registered as soon as they have an id.
129      * @param String $module
130      * @param SugarBean $bean
131      * @param bool|String $id
132      * @return bool true if the bean registered successfully.
133      */
134     public static function registerBean($module, $bean, $id=false)
135     {
136         global $beanList;
137         if (empty($beanList[$module]))  return false;
138
139         if (!isset(self::$loadedBeans[$module]))
140             self::$loadedBeans[$module] = array();
141
142         //Do not double register a bean
143         if (!empty($id) && isset(self::$loadedBeans[$module][$id]))
144             return true;
145
146         $index = "i" . (self::$total % self::$maxLoaded);
147         //We should only hold a limited number of beans in memory at a time.
148         //Once we have the max, unload the oldest bean.
149         if (count(self::$loadOrder) >= self::$maxLoaded - 1)
150         {
151             for($i = 0; $i < self::$maxLoaded; $i++)
152             {
153                 if (isset(self::$loadOrder[$index]))
154                 {
155                     $info = self::$loadOrder[$index];
156                     //If a bean isn't in the database yet, we need to hold onto it.
157                     if (!empty(self::$loadedBeans[$info['module']][$info['id']]->in_save))
158                     {
159                         self::$total++;
160                     }
161                     //Beans that have been used recently should be held in memory if possible
162                     else if (!empty(self::$touched[$info['module']][$info['id']]) && self::$touched[$info['module']][$info['id']] > 0)
163                     {
164                         self::$touched[$info['module']][$info['id']]--;
165                         self::$total++;
166                     }
167                     else
168                         break;
169                 } else {
170                     break;
171                 }
172                 $index = "i" . (self::$total % self::$maxLoaded);
173             }
174             if (isset(self::$loadOrder[$index]))
175             {
176                 unset(self::$loadedBeans[$info['module']][$info['id']]);
177                 unset(self::$touched[$info['module']][$info['id']]);
178                 unset(self::$loadOrder[$index]);
179             }
180         }
181
182         if(!empty($bean->id))
183            $id = $bean->id;
184
185         if ($id)
186         {
187             self::$loadedBeans[$module][$id] = $bean;
188             self::$total++;
189             self::$loadOrder[$index] = array("module" => $module, "id" => $id);
190             self::$touched[$module][$id] = 0;
191         } else{
192             return false;
193         }
194         return true;
195     }
196 }
197