PageRenderTime 46ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/administrator/components/com_virtuemart/classes/ps_perm.php

https://github.com/Shigaru/shigaru
PHP | 461 lines | 285 code | 55 blank | 121 comment | 75 complexity | a1c9489bb9b1607050504fdd0a274531 MD5 | raw file
  1. <?php
  2. if( !defined( '_VALID_MOS' ) && !defined( '_JEXEC' ) ) die( 'Direct Access to '.basename(__FILE__).' is not allowed.' );
  3. /**
  4. *
  5. * @version $Id: ps_perm.php 1818 2009-06-23 19:07:21Z soeren_nb $
  6. * @package VirtueMart
  7. * @subpackage classes
  8. * @copyright Copyright (C) 2004-2009 soeren - All rights reserved.
  9. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
  10. * VirtueMart is free software. This version may have been modified pursuant
  11. * to the GNU General Public License, and as distributed it includes or
  12. * is derivative of works licensed under the GNU General Public License or
  13. * other free or open source software licenses.
  14. * See /administrator/components/com_virtuemart/COPYRIGHT.php for copyright notices and details.
  15. *
  16. * http://virtuemart.net
  17. */
  18. /**
  19. * The permission handler class for VirtueMart.
  20. *
  21. */
  22. class vm_ps_perm {
  23. var $user_groups;
  24. function vm_ps_perm() {
  25. $this->user_groups = array();
  26. $this->getUserGroups();
  27. }
  28. function getUserGroups() {
  29. if( empty( $this->user_groups )) {
  30. $db = new ps_DB();
  31. $db->query('SELECT group_id,group_name,group_level FROM `#__{vm}_auth_group` ORDER BY group_level');
  32. while( $db->next_record() ) {
  33. $this->user_groups[$db->f('group_name')] = $db->f('group_level');
  34. }
  35. }
  36. return $this->user_groups;
  37. }
  38. /**
  39. * This function does the basic authentication
  40. * for a user in the shop.
  41. * It assigns permissions, the name, country, zip and
  42. * the shopper group id with the user and the session.
  43. * @return array Authentication information
  44. */
  45. function doAuthentication( $shopper_group ) {
  46. global $my, $acl, $user;
  47. $db = new ps_DB;
  48. $auth = !empty( $_SESSION['auth']) ? $_SESSION['auth'] : array();
  49. if( class_exists('jfactory')) {
  50. $vmUser = JFactory::getUser();
  51. } else {
  52. $vmUser =& $my;
  53. }
  54. if( VM_PRICE_ACCESS_LEVEL != '' ) {
  55. // Get the usertype property when not present
  56. if( empty( $vmUser->usertype ) ) {
  57. if( empty( $vmUser->id )) {
  58. $gid = 29;
  59. }
  60. else {
  61. $gid = $vmUser->gid;
  62. }
  63. $fieldname = vmIsJoomla( '1.5' ) ? 'id' : 'group_id';
  64. $db->query( 'SELECT `name` FROM `#__core_acl_aro_groups` WHERE `'.$fieldname.'` ='.$gid );
  65. $db->next_record();
  66. $vmUser->usertype = $db->f( 'name' );
  67. }
  68. $this->prepareACL();
  69. // Is the user allowed to see the prices?
  70. // this code will change when Joomla has a good ACL implementation
  71. if( is_callable( array( $user, 'authorize'))) {
  72. $auth['show_prices'] = $user->authorize( 'virtuemart', 'prices' );
  73. }
  74. else {
  75. $auth['show_prices'] = $acl->acl_check( 'virtuemart', 'prices', 'users', strtolower($vmUser->usertype), null, null );
  76. }
  77. }
  78. else {
  79. $auth['show_prices'] = 1;
  80. }
  81. if (!empty($vmUser->id) || !empty( $auth['user_id'])) { // user has already logged in
  82. if( $vmUser->id > 0 ) {
  83. $auth["user_id"] = $vmUser->id;
  84. $auth["username"] = $vmUser->username;
  85. } elseif( !empty( $auth['user_id']) && VM_REGISTRATION_TYPE != 'NO_REGISTRATION' && VM_REGISTRATION_TYPE != 'OPTIONAL_REGISTRATION') {
  86. $auth["user_id"] = 0;
  87. $auth["username"] = "demo";
  88. }
  89. if ($this->is_registered_customer($auth["user_id"])) {
  90. $q = "SELECT perms,first_name,last_name,country,zip FROM #__{vm}_user_info WHERE user_id='".$auth["user_id"]."'";
  91. $db->query($q);
  92. $db->next_record();
  93. $auth["perms"] = $db->f("perms");
  94. $auth["first_name"] = $db->f("first_name");
  95. $auth["last_name"] = $db->f("last_name");
  96. $auth["country"] = $db->f("country");
  97. $auth["zip"] = $db->f("zip");
  98. // Shopper is the default value
  99. // We must prevent that Administrators or Managers are 'just' shoppers
  100. if( $auth["perms"] == "shopper" ) {
  101. if (stristr($vmUser->usertype,"Administrator")) {
  102. $auth["perms"] = "admin";
  103. }
  104. elseif (stristr($vmUser->usertype,"Manager")) {
  105. $auth["perms"] = "storeadmin";
  106. }
  107. }
  108. $auth["shopper_group_id"] = $shopper_group["shopper_group_id"];
  109. $auth["shopper_group_discount"] = $shopper_group["shopper_group_discount"];
  110. $auth["show_price_including_tax"] = $shopper_group["show_price_including_tax"];
  111. $auth["default_shopper_group"] = $shopper_group["default_shopper_group"];
  112. $auth["is_registered_customer"] = true;
  113. }
  114. // user is no registered customer
  115. else {
  116. if (stristr($vmUser->usertype,"Administrator")) {
  117. $auth["perms"] = "admin";
  118. }
  119. elseif (stristr($vmUser->usertype,"Manager")) {
  120. $auth["perms"] = "storeadmin";
  121. }
  122. else {
  123. $auth["perms"] = "shopper"; // DEFAULT
  124. }
  125. $auth["shopper_group_id"] = $shopper_group["shopper_group_id"];
  126. $auth["shopper_group_discount"] = $shopper_group["shopper_group_discount"];
  127. $auth["show_price_including_tax"] = $shopper_group["show_price_including_tax"];
  128. $auth["default_shopper_group"] = 1;
  129. $auth["is_registered_customer"] = false;
  130. }
  131. } // user is not logged in
  132. elseif( empty( $auth['user_id']) ) {
  133. $auth["user_id"] = 0;
  134. $auth["username"] = "demo";
  135. $auth["perms"] = "";
  136. $auth["first_name"] = "guest";
  137. $auth["last_name"] = "";
  138. $auth["shopper_group_id"] = $shopper_group["shopper_group_id"];
  139. $auth["shopper_group_discount"] = $shopper_group["shopper_group_discount"];
  140. $auth["show_price_including_tax"] = $shopper_group["show_price_including_tax"];
  141. $auth["default_shopper_group"] = 1;
  142. $auth["is_registered_customer"] = false;
  143. }
  144. // register $auth into SESSION
  145. $_SESSION['auth'] = $auth;
  146. return $auth;
  147. }
  148. /**
  149. * Validates the permission to do something.
  150. *
  151. * @param string $perms
  152. * @return boolean Check successful or not
  153. * @example $perm->check( 'admin', 'storeadmin' );
  154. * returns true when the user is admin or storeadmin
  155. */
  156. function check($perms) {
  157. $auth = $_SESSION["auth"];
  158. // Parse all permissions in argument, comma separated
  159. // It is assumed auth_user only has one group per user.
  160. if ($perms == "none") {
  161. return True;
  162. }
  163. else {
  164. $p1 = explode(",", $auth['perms']);
  165. $p2 = explode(",", $perms);
  166. while (list($key1, $value1) = each($p1)) {
  167. while (list($key2, $value2) = each($p2)) {
  168. if ($auth['perms'] && $this->user_groups[$value2]
  169. >= $this->user_groups[$auth['perms']]) {
  170. return True;
  171. }
  172. }
  173. }
  174. }
  175. return False;
  176. }
  177. /**
  178. * Checks if the user has higher permissions than $perm
  179. *
  180. * @param string $perm
  181. * @return boolean
  182. * @example $perm->hasHigherPerms( 'storeadmin' );
  183. * returns true when user is admin
  184. */
  185. function hasHigherPerms( $perm ) {
  186. $auth = $_SESSION["auth"];
  187. if( $auth['perms'] && $this->user_groups[$perm] >= $this->user_groups[$auth['perms']] ) {
  188. return true;
  189. }
  190. else {
  191. return false;
  192. }
  193. }
  194. /**
  195. * lists the permission levels in a select box
  196. * @author pablo
  197. * @param string $name The name of the select element
  198. * @param string $group_name The preselected key
  199. */
  200. function list_perms( $name, $group_name, $size=1, $multi=false ) {
  201. global $VM_LANG;
  202. $auth = $_SESSION['auth'];
  203. if( $multi ) {
  204. $multi = 'multiple="multiple"';
  205. }
  206. $db = new ps_DB;
  207. // Get users current permission value
  208. $dvalue = $this->user_groups[$auth["perms"]];
  209. $perms = $this->getUserGroups();
  210. arsort( $perms );
  211. if( $size==1 ) {
  212. $values[0] = $VM_LANG->_('PHPSHOP_SELECT');
  213. }
  214. while( list($key,$value) = each( $perms ) ) {
  215. // Display only those permission that this user can set
  216. if ($value >= $dvalue) {
  217. $values[$key] = $key;
  218. }
  219. }
  220. if( $size > 1 ) {
  221. $name .= '[]';
  222. $values['none'] = $VM_LANG->_('NO_RESTRICTION');
  223. }
  224. echo ps_html::selectList( $name, $group_name, $values, $size, $multi );
  225. }
  226. /**************************************************************************
  227. ** name: is_registered_customer()
  228. ** created by: soeren
  229. ** description: Validates if someone is registered customer.
  230. ** by checking if one has a billing address
  231. ** parameters: user_id
  232. ** returns: true if the user has a BT address
  233. ** false if the user has none
  234. ***************************************************************************/
  235. /**
  236. * Check if a user is registered in the shop (=customer)
  237. *
  238. * @param int $user_id
  239. * @return boolean
  240. */
  241. function is_registered_customer($user_id) {
  242. if( $user_id == 0 ) return false;
  243. $db_check = new ps_DB;
  244. // If the registration type is neither "no registration" nor "optional registration", there *must* be a related Joomla! user, we can join
  245. if( VM_REGISTRATION_TYPE != 'NO_REGISTRATION' && VM_REGISTRATION_TYPE != 'OPTIONAL_REGISTRATION' ) {
  246. $q = "SELECT COUNT(user_id) as num_rows FROM `#__{vm}_user_info`, `#__users`
  247. WHERE `id`=`user_id`
  248. AND #__{vm}_user_info.user_id='" . $user_id . "'
  249. AND #__{vm}_user_info.address_type='BT'";
  250. } else {
  251. $q = "SELECT COUNT(user_id) as num_rows FROM `#__{vm}_user_info`
  252. WHERE #__{vm}_user_info.user_id='" . $user_id . "'
  253. AND #__{vm}_user_info.address_type='BT'";
  254. }
  255. $db_check->query($q);
  256. $db_check->next_record();
  257. // Query failed or not?
  258. return $db_check->f('num_rows') > 0;
  259. }
  260. /**
  261. * HERE WE INSERT GROUPS THAT ARE ALLOWED TO VIEW PRICES
  262. *
  263. */
  264. function prepareACL() {
  265. global $acl;
  266. // The basic ACL integration in Mambo/Joomla is not awesome
  267. $child_groups = ps_perm::getChildGroups( '#__core_acl_aro_groups', 'g1.group_id, g1.name, COUNT(g2.name) AS level', 'g1.name', null, VM_PRICE_ACCESS_LEVEL );
  268. foreach( $child_groups as $child_group ) {
  269. ps_perm::_addToGlobalACL( 'virtuemart', 'prices', 'users', $child_group->name, null, null );
  270. }
  271. $admin_groups = ps_perm::getChildGroups( '#__core_acl_aro_groups', 'g1.group_id, g1.name, COUNT(g2.name) AS level', 'g1.name', null, 'Public Backend' );
  272. foreach( $admin_groups as $child_group ) {
  273. ps_perm::_addToGlobalACL( 'virtuemart', 'prices', 'users', $child_group->name, null, null );
  274. }
  275. }
  276. /**
  277. * Function from an old Mambo phpgacl integration function
  278. * @deprecated (but necessary, sigh!)
  279. * @static
  280. * @param string $table
  281. * @param string $fields
  282. * @param string $groupby
  283. * @param int $root_id
  284. * @param string $root_name
  285. * @param boolean $inclusive
  286. * @return array
  287. */
  288. function getChildGroups( $table, $fields, $groupby=null, $root_id=null, $root_name=null, $inclusive=true ) {
  289. global $database, $_VERSION;
  290. $root = new stdClass();
  291. $root->lft = 0;
  292. $root->rgt = 0;
  293. if( vmIsJoomla( '1.5' ) ) {
  294. $fields = str_replace( 'group_id', 'id', $fields );
  295. }
  296. if ($root_id) {
  297. } else if ($root_name) {
  298. $database->setQuery( "SELECT `lft`, `rgt` FROM `$table` WHERE `name`='$root_name'" );
  299. if( vmIsJoomla( '1.5' ) && !defined( '_JLEGACY' ) ) {
  300. $root = $database->loadObject();
  301. } else {
  302. $database->loadObject( $root );
  303. }
  304. }
  305. $where = '';
  306. if ($root->lft+$root->rgt != 0) {
  307. if ($inclusive) {
  308. $where = "WHERE g1.lft BETWEEN $root->lft AND $root->rgt";
  309. } else {
  310. $where = "WHERE g1.lft BETWEEN $root->lft+1 AND $root->rgt-1";
  311. }
  312. }
  313. $database->setQuery( "SELECT $fields"
  314. . "\nFROM $table AS g1"
  315. . "\nINNER JOIN $table AS g2 ON g1.lft BETWEEN g2.lft AND g2.rgt"
  316. . "\n$where"
  317. . ($groupby ? "\nGROUP BY $groupby" : "")
  318. . "\nORDER BY g1.lft"
  319. );
  320. $result = $database->loadObjectList();
  321. return is_array($result) ? $result : array();
  322. }
  323. /**
  324. * This is a temporary function to allow 3PD's to add basic ACL checks for their
  325. * modules and components. NOTE: this information will be compiled in the db
  326. * in future versions
  327. * @static
  328. * @param unknown_type $aco_section_value
  329. * @param unknown_type $aco_value
  330. * @param unknown_type $aro_section_value
  331. * @param unknown_type $aro_value
  332. * @param unknown_type $axo_section_value
  333. * @param unknown_type $axo_value
  334. */
  335. function _addToGlobalACL( $aco_section_value, $aco_value,
  336. $aro_section_value, $aro_value, $axo_section_value=NULL, $axo_value=NULL ) {
  337. global $acl;
  338. $acl->acl[] = array( $aco_section_value, $aco_value, $aro_section_value, $aro_value, $axo_section_value, $axo_value );
  339. $acl->acl_count = count( $acl->acl );
  340. }
  341. /**
  342. * Returns a tree with the children of the root group id
  343. * @static
  344. * @param int $root_id
  345. * @param string $root_name
  346. * @param boolean $inclusive
  347. * @return unknown
  348. */
  349. function getGroupChildrenTree( $root_id=null, $root_name=null, $inclusive=true ) {
  350. global $database, $_VERSION;
  351. $tree = ps_perm::getChildGroups( '#__core_acl_aro_groups',
  352. 'g1.group_id, g1.name, COUNT(g2.name) AS level',
  353. 'g1.name',
  354. $root_id, $root_name, $inclusive );
  355. // first pass get level limits
  356. $n = count( $tree );
  357. $min = $tree[0]->level;
  358. $max = $tree[0]->level;
  359. for ($i=0; $i < $n; $i++) {
  360. $min = min( $min, $tree[$i]->level );
  361. $max = max( $max, $tree[$i]->level );
  362. }
  363. $indents = array();
  364. foreach (range( $min, $max ) as $i) {
  365. $indents[$i] = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
  366. }
  367. // correction for first indent
  368. $indents[$min] = '';
  369. $list = array();
  370. for ($i=$n-1; $i >= 0; $i--) {
  371. $shim = '';
  372. foreach (range( $min, $tree[$i]->level ) as $j) {
  373. $shim .= $indents[$j];
  374. }
  375. if (@$indents[$tree[$i]->level+1] == '.&nbsp;') {
  376. $twist = '&nbsp;';
  377. } else {
  378. $twist = "-&nbsp;";
  379. }
  380. if( $_VERSION->PRODUCT == 'Joomla!' && $_VERSION->RELEASE >= 1.5 ) {
  381. $tree[$i]->group_id = $tree[$i]->id;
  382. }
  383. $list[$tree[$i]->group_id] = $shim.$twist.$tree[$i]->name;
  384. if ($tree[$i]->level < @$tree[$i-1]->level) {
  385. $indents[$tree[$i]->level+1] = '.&nbsp;';
  386. }
  387. }
  388. ksort($list);
  389. return $list;
  390. }
  391. }
  392. // Check if there is an extended class in the Themes and if it is allowed to use them
  393. // If the class is called outside Virtuemart, we have to make sure to load the settings
  394. // Thomas Kahl - Feb. 2009
  395. if (!defined('VM_ALLOW_EXTENDED_CLASSES') && file_exists(dirname(__FILE__).'/../virtuemart.cfg.php')) {
  396. include_once(dirname(__FILE__).'/../virtuemart.cfg.php');
  397. }
  398. // If settings are loaded, extended Classes are allowed and the class exisits...
  399. if (defined('VM_ALLOW_EXTENDED_CLASSES') && defined('VM_THEMEPATH') && VM_ALLOW_EXTENDED_CLASSES && file_exists(VM_THEMEPATH.'user_class/'.basename(__FILE__))) {
  400. // Load the theme-user_class as extended
  401. include_once(VM_THEMEPATH.'user_class/'.basename(__FILE__));
  402. } else {
  403. // Otherwise we have to use the original classname to extend the core-class
  404. class ps_perm extends vm_ps_perm {}
  405. }
  406. ?>