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