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