PageRenderTime 65ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/t3lib/class.t3lib_userauthgroup.php

https://github.com/andreaswolf/typo3-tceforms
PHP | 1925 lines | 1080 code | 179 blank | 666 comment | 302 complexity | 8a3bb033d5028c0c498c9220838a1eb9 MD5 | raw file
Possible License(s): Apache-2.0, BSD-2-Clause, LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /***************************************************************
  3. * Copyright notice
  4. *
  5. * (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
  6. * All rights reserved
  7. *
  8. * This script is part of the TYPO3 project. The TYPO3 project is
  9. * free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * The GNU General Public License can be found at
  15. * http://www.gnu.org/copyleft/gpl.html.
  16. * A copy is found in the textfile GPL.txt and important notices to the license
  17. * from the author is found in LICENSE.txt distributed with these scripts.
  18. *
  19. *
  20. * This script is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. * GNU General Public License for more details.
  24. *
  25. * This copyright notice MUST APPEAR in all copies of the script!
  26. ***************************************************************/
  27. /**
  28. * Contains an extension class specifically for authentication/initialization of backend users in TYPO3
  29. *
  30. * $Id$
  31. * Revised for TYPO3 3.6 July/2003 by Kasper Skårhøj
  32. *
  33. * @author Kasper Skårhøj <kasperYYYY@typo3.com>
  34. */
  35. /**
  36. * [CLASS/FUNCTION INDEX of SCRIPT]
  37. *
  38. *
  39. *
  40. * 135: class t3lib_userAuthGroup extends t3lib_userAuth
  41. *
  42. * SECTION: Permission checking functions:
  43. * 199: function isAdmin()
  44. * 211: function isMemberOfGroup($groupId)
  45. * 233: function doesUserHaveAccess($row,$perms)
  46. * 250: function isInWebMount($id,$readPerms='',$exitOnError=0)
  47. * 277: function modAccess($conf,$exitOnError)
  48. * 328: function getPagePermsClause($perms)
  49. * 367: function calcPerms($row)
  50. * 405: function isRTE()
  51. * 439: function check($type,$value)
  52. * 456: function checkAuthMode($table,$field,$value,$authMode)
  53. * 522: function checkLanguageAccess($langValue)
  54. * 544: function recordEditAccessInternals($table,$idOrRow,$newRecord=FALSE)
  55. * 619: function isPSet($lCP,$table,$type='')
  56. * 636: function mayMakeShortcut()
  57. * 650: function workspaceCannotEditRecord($table,$recData)
  58. * 689: function workspaceCannotEditOfflineVersion($table,$recData)
  59. * 712: function workspaceAllowLiveRecordsInPID($pid, $table)
  60. * 733: function workspaceCreateNewRecord($pid, $table)
  61. * 752: function workspaceAllowAutoCreation($table,$id,$recpid)
  62. * 772: function workspaceCheckStageForCurrent($stage)
  63. * 795: function workspacePublishAccess($wsid)
  64. * 823: function workspaceSwapAccess()
  65. * 835: function workspaceVersioningTypeAccess($type)
  66. * 866: function workspaceVersioningTypeGetClosest($type)
  67. *
  68. * SECTION: Miscellaneous functions
  69. * 909: function getTSConfig($objectString,$config='')
  70. * 935: function getTSConfigVal($objectString)
  71. * 947: function getTSConfigProp($objectString)
  72. * 959: function inList($in_list,$item)
  73. * 970: function returnWebmounts()
  74. * 980: function returnFilemounts()
  75. * 997: function jsConfirmation($bitmask)
  76. *
  77. * SECTION: Authentication methods
  78. * 1035: function fetchGroupData()
  79. * 1168: function fetchGroups($grList,$idList='')
  80. * 1266: function setCachedList($cList)
  81. * 1286: function addFileMount($title, $altTitle, $path, $webspace, $type)
  82. * 1333: function addTScomment($str)
  83. *
  84. * SECTION: Workspaces
  85. * 1369: function workspaceInit()
  86. * 1412: function checkWorkspace($wsRec,$fields='uid,title,adminusers,members,reviewers,publish_access,stagechg_notification')
  87. * 1487: function checkWorkspaceCurrent()
  88. * 1500: function setWorkspace($workspaceId)
  89. * 1528: function setWorkspacePreview($previewState)
  90. * 1538: function getDefaultWorkspace()
  91. *
  92. * SECTION: Logging
  93. * 1589: function writelog($type,$action,$error,$details_nr,$details,$data,$tablename='',$recuid='',$recpid='',$event_pid=-1,$NEWid='',$userId=0)
  94. * 1621: function simplelog($message, $extKey='', $error=0)
  95. * 1642: function checkLogFailures($email, $secondsBack=3600, $max=3)
  96. *
  97. * TOTAL FUNCTIONS: 45
  98. * (This index is automatically created/updated by the extension "extdeveval")
  99. *
  100. */
  101. /**
  102. * Extension to class.t3lib_userauth.php; Authentication of users in TYPO3 Backend
  103. *
  104. * Actually this class is extended again by t3lib_beuserauth which is the actual backend user class that will be instantiated.
  105. * In fact the two classes t3lib_beuserauth and this class could just as well be one, single class since t3lib_userauthgroup is not - to my knowledge - used separately elsewhere. But for historical reasons they are two separate classes.
  106. *
  107. * @author Kasper Skårhøj <kasperYYYY@typo3.com>
  108. * @package TYPO3
  109. * @subpackage t3lib
  110. */
  111. class t3lib_userAuthGroup extends t3lib_userAuth {
  112. var $usergroup_column = 'usergroup'; // Should be set to the usergroup-column (id-list) in the user-record
  113. var $usergroup_table = 'be_groups'; // The name of the group-table
  114. // internal
  115. var $groupData = array( // This array holds lists of eg. tables, fields and other values related to the permission-system. See fetchGroupData
  116. 'filemounts' => array() // Filemounts are loaded here
  117. );
  118. var $workspace = -99; // User workspace. -99 is ERROR (none available), -1 is offline, 0 is online, >0 is custom workspaces.
  119. var $workspaceRec = array(); // Custom workspace record if any
  120. var $userGroups = array(); // This array will hold the groups that the user is a member of
  121. var $userGroupsUID = array(); // This array holds the uid's of the groups in the listed order
  122. var $groupList = ''; // This is $this->userGroupsUID imploded to a comma list... Will correspond to the 'usergroup_cached_list'
  123. var $dataLists = array( // Used internally to accumulate data for the user-group. DONT USE THIS EXTERNALLY! Use $this->groupData instead
  124. 'webmount_list' => '',
  125. 'filemount_list' => '',
  126. 'fileoper_perms' => 0,
  127. 'modList' => '',
  128. 'tables_select' => '',
  129. 'tables_modify' => '',
  130. 'pagetypes_select' => '',
  131. 'non_exclude_fields' => '',
  132. 'explicit_allowdeny' => '',
  133. 'allowed_languages' => '',
  134. 'workspace_perms' => '',
  135. 'custom_options' => '',
  136. );
  137. var $includeHierarchy = array(); // For debugging/display of order in which subgroups are included.
  138. var $includeGroupArray = array(); // List of group_id's in the order they are processed.
  139. var $OS = ''; // Set to 'WIN', if windows
  140. var $TSdataArray = array(); // Used to accumulate the TSconfig data of the user
  141. var $userTS_text = ''; // Contains the non-parsed user TSconfig
  142. var $userTS = array(); // Contains the parsed user TSconfig
  143. var $userTSUpdated = 0; // Set internally if the user TSconfig was parsed and needs to be cached.
  144. var $userTS_dontGetCached = 0; // Set this from outside if you want the user TSconfig to ALWAYS be parsed and not fetched from cache.
  145. var $RTE_errors = array(); // RTE availability errors collected.
  146. var $errorMsg = ''; // Contains last error message
  147. var $checkWorkspaceCurrent_cache = NULL; // Cache for checkWorkspaceCurrent()
  148. /************************************
  149. *
  150. * Permission checking functions:
  151. *
  152. ************************************/
  153. /**
  154. * Returns true if user is admin
  155. * Basically this function evaluates if the ->user[admin] field has bit 0 set. If so, user is admin.
  156. *
  157. * @return boolean
  158. */
  159. function isAdmin() {
  160. return (($this->user['admin'] & 1) == 1);
  161. }
  162. /**
  163. * Returns true if the current user is a member of group $groupId
  164. * $groupId must be set. $this->groupList must contain groups
  165. * Will return true also if the user is a member of a group through subgroups.
  166. *
  167. * @param integer Group ID to look for in $this->groupList
  168. * @return boolean
  169. */
  170. function isMemberOfGroup($groupId) {
  171. $groupId = intval($groupId);
  172. if ($this->groupList && $groupId) {
  173. return $this->inList($this->groupList, $groupId);
  174. }
  175. }
  176. /**
  177. * Checks if the permissions is granted based on a page-record ($row) and $perms (binary and'ed)
  178. *
  179. * Bits for permissions, see $perms variable:
  180. *
  181. * 1 - Show: See/Copy page and the pagecontent.
  182. * 16- Edit pagecontent: Change/Add/Delete/Move pagecontent.
  183. * 2- Edit page: Change/Move the page, eg. change title, startdate, hidden.
  184. * 4- Delete page: Delete the page and pagecontent.
  185. * 8- New pages: Create new pages under the page.
  186. *
  187. * @param array $row is the pagerow for which the permissions is checked
  188. * @param integer $perms is the binary representation of the permission we are going to check. Every bit in this number represents a permission that must be set. See function explanation.
  189. * @return boolean True or False upon evaluation
  190. */
  191. function doesUserHaveAccess($row, $perms) {
  192. $userPerms = $this->calcPerms($row);
  193. return ($userPerms & $perms) == $perms;
  194. }
  195. /**
  196. * Checks if the page id, $id, is found within the webmounts set up for the user.
  197. * This should ALWAYS be checked for any page id a user works with, whether it's about reading, writing or whatever.
  198. * The point is that this will add the security that a user can NEVER touch parts outside his mounted pages in the page tree. This is otherwise possible if the raw page permissions allows for it. So this security check just makes it easier to make safe user configurations.
  199. * If the user is admin OR if this feature is disabled (fx. by setting TYPO3_CONF_VARS['BE']['lockBeUserToDBmounts']=0) then it returns "1" right away
  200. * Otherwise the function will return the uid of the webmount which was first found in the rootline of the input page $id
  201. *
  202. * @param integer Page ID to check
  203. * @param string Content of "->getPagePermsClause(1)" (read-permissions). If not set, they will be internally calculated (but if you have the correct value right away you can save that database lookup!)
  204. * @param boolean If set, then the function will exit with an error message.
  205. * @return integer The page UID of a page in the rootline that matched a mount point
  206. */
  207. function isInWebMount($id, $readPerms = '', $exitOnError = 0) {
  208. if (!$GLOBALS['TYPO3_CONF_VARS']['BE']['lockBeUserToDBmounts'] || $this->isAdmin()) {
  209. return 1;
  210. }
  211. $id = intval($id);
  212. // Check if input id is an offline version page in which case we will map id to the online version:
  213. $checkRec = t3lib_beFUnc::getRecord('pages', $id, 'pid,t3ver_oid');
  214. if ($checkRec['pid'] == -1) {
  215. $id = intval($checkRec['t3ver_oid']);
  216. }
  217. if (!$readPerms) {
  218. $readPerms = $this->getPagePermsClause(1);
  219. }
  220. if ($id > 0) {
  221. $wM = $this->returnWebmounts();
  222. $rL = t3lib_BEfunc::BEgetRootLine($id, ' AND ' . $readPerms);
  223. foreach ($rL as $v) {
  224. if ($v['uid'] && in_array($v['uid'], $wM)) {
  225. return $v['uid'];
  226. }
  227. }
  228. }
  229. if ($exitOnError) {
  230. throw new RuntimeException('Access Error: This page is not within your DB-mounts', 1294586445);
  231. }
  232. }
  233. /**
  234. * Checks access to a backend module with the $MCONF passed as first argument
  235. *
  236. * @param array $MCONF array of a backend module!
  237. * @param boolean If set, an array will issue an error message and exit.
  238. * @return boolean Will return true if $MCONF['access'] is not set at all, if the BE_USER is admin or if the module is enabled in the be_users/be_groups records of the user (specifically enabled). Will return false if the module name is not even found in $TBE_MODULES
  239. */
  240. function modAccess($conf, $exitOnError) {
  241. if (!t3lib_BEfunc::isModuleSetInTBE_MODULES($conf['name'])) {
  242. if ($exitOnError) {
  243. throw new RuntimeException('Fatal Error: This module "' . $conf['name'] . '" is not enabled in TBE_MODULES', 1294586446);
  244. }
  245. return FALSE;
  246. }
  247. // Workspaces check:
  248. if ($conf['workspaces']) {
  249. if (($this->workspace === 0 && t3lib_div::inList($conf['workspaces'], 'online')) ||
  250. ($this->workspace === -1 && t3lib_div::inList($conf['workspaces'], 'offline')) ||
  251. ($this->workspace > 0 && t3lib_div::inList($conf['workspaces'], 'custom'))) {
  252. // ok, go on...
  253. } else {
  254. if ($exitOnError) {
  255. throw new RuntimeException('Workspace Error: This module "' . $conf['name'] . '" is not available under the current workspace', 1294586447);
  256. }
  257. return FALSE;
  258. }
  259. }
  260. // Returns true if conf[access] is not set at all or if the user is admin
  261. if (!$conf['access'] || $this->isAdmin()) {
  262. return TRUE;
  263. }
  264. // If $conf['access'] is set but not with 'admin' then we return true, if the module is found in the modList
  265. if (!strstr($conf['access'], 'admin') && $conf['name']) {
  266. $acs = $this->check('modules', $conf['name']);
  267. }
  268. if (!$acs && $exitOnError) {
  269. throw new RuntimeException('Access Error: You don\'t have access to this module.', 1294586448);
  270. } else {
  271. return $acs;
  272. }
  273. }
  274. /**
  275. * Returns a WHERE-clause for the pages-table where user permissions according to input argument, $perms, is validated.
  276. * $perms is the "mask" used to select. Fx. if $perms is 1 then you'll get all pages that a user can actually see!
  277. * 2^0 = show (1)
  278. * 2^1 = edit (2)
  279. * 2^2 = delete (4)
  280. * 2^3 = new (8)
  281. * If the user is 'admin' " 1=1" is returned (no effect)
  282. * If the user is not set at all (->user is not an array), then " 1=0" is returned (will cause no selection results at all)
  283. * The 95% use of this function is "->getPagePermsClause(1)" which will return WHERE clauses for *selecting* pages in backend listings - in other words this will check read permissions.
  284. *
  285. * @param integer Permission mask to use, see function description
  286. * @return string Part of where clause. Prefix " AND " to this.
  287. */
  288. function getPagePermsClause($perms) {
  289. global $TYPO3_CONF_VARS;
  290. if (is_array($this->user)) {
  291. if ($this->isAdmin()) {
  292. return ' 1=1';
  293. }
  294. $perms = intval($perms); // Make sure it's integer.
  295. $str = ' (' .
  296. '(pages.perms_everybody & ' . $perms . ' = ' . $perms . ')' . // Everybody
  297. ' OR (pages.perms_userid = ' . $this->user['uid'] . ' AND pages.perms_user & ' . $perms . ' = ' . $perms . ')'; // User
  298. if ($this->groupList) {
  299. $str .= ' OR (pages.perms_groupid in (' . $this->groupList . ') AND pages.perms_group & ' . $perms . ' = ' . $perms . ')'; // Group (if any is set)
  300. }
  301. $str .= ')';
  302. // ****************
  303. // getPagePermsClause-HOOK
  304. // ****************
  305. if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['getPagePermsClause'])) {
  306. foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['getPagePermsClause'] as $_funcRef) {
  307. $_params = array('currentClause' => $str, 'perms' => $perms);
  308. $str = t3lib_div::callUserFunction($_funcRef, $_params, $this);
  309. }
  310. }
  311. return $str;
  312. } else {
  313. return ' 1=0';
  314. }
  315. }
  316. /**
  317. * Returns a combined binary representation of the current users permissions for the page-record, $row.
  318. * The perms for user, group and everybody is OR'ed together (provided that the page-owner is the user and for the groups that the user is a member of the group
  319. * If the user is admin, 31 is returned (full permissions for all five flags)
  320. *
  321. * @param array Input page row with all perms_* fields available.
  322. * @return integer Bitwise representation of the users permissions in relation to input page row, $row
  323. */
  324. function calcPerms($row) {
  325. global $TYPO3_CONF_VARS;
  326. if ($this->isAdmin()) {
  327. return 31;
  328. } // Return 31 for admin users.
  329. $out = 0;
  330. if (isset($row['perms_userid']) && isset($row['perms_user']) && isset($row['perms_groupid']) && isset($row['perms_group']) && isset($row['perms_everybody']) && isset($this->groupList)) {
  331. if ($this->user['uid'] == $row['perms_userid']) {
  332. $out |= $row['perms_user'];
  333. }
  334. if ($this->isMemberOfGroup($row['perms_groupid'])) {
  335. $out |= $row['perms_group'];
  336. }
  337. $out |= $row['perms_everybody'];
  338. }
  339. // ****************
  340. // CALCPERMS hook
  341. // ****************
  342. if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['calcPerms'])) {
  343. foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['calcPerms'] as $_funcRef) {
  344. $_params = array(
  345. 'row' => $row,
  346. 'outputPermissions' => $out
  347. );
  348. $out = t3lib_div::callUserFunction($_funcRef, $_params, $this);
  349. }
  350. }
  351. return $out;
  352. }
  353. /**
  354. * Returns true if the RTE (Rich Text Editor) can be enabled for the user
  355. * Strictly this is not permissions being checked but rather a series of settings like a loaded extension, browser/client type and a configuration option in ->uc[edit_RTE]
  356. * The reasons for a FALSE return can be found in $this->RTE_errors
  357. *
  358. * @return boolean
  359. */
  360. function isRTE() {
  361. global $CLIENT;
  362. // Start:
  363. $this->RTE_errors = array();
  364. if (!$this->uc['edit_RTE']) {
  365. $this->RTE_errors[] = 'RTE is not enabled for user!';
  366. }
  367. if (!$GLOBALS['TYPO3_CONF_VARS']['BE']['RTEenabled']) {
  368. $this->RTE_errors[] = 'RTE is not enabled in $TYPO3_CONF_VARS["BE"]["RTEenabled"]';
  369. }
  370. // Acquire RTE object:
  371. $RTE = t3lib_BEfunc::RTEgetObj();
  372. if (!is_object($RTE)) {
  373. $this->RTE_errors = array_merge($this->RTE_errors, $RTE);
  374. }
  375. if (!count($this->RTE_errors)) {
  376. return TRUE;
  377. } else {
  378. return FALSE;
  379. }
  380. }
  381. /**
  382. * Returns true if the $value is found in the list in a $this->groupData[] index pointed to by $type (array key).
  383. * Can thus be users to check for modules, exclude-fields, select/modify permissions for tables etc.
  384. * If user is admin true is also returned
  385. * Please see the document Inside TYPO3 for examples.
  386. *
  387. * @param string The type value; "webmounts", "filemounts", "pagetypes_select", "tables_select", "tables_modify", "non_exclude_fields", "modules"
  388. * @param string String to search for in the groupData-list
  389. * @return boolean True if permission is granted (that is, the value was found in the groupData list - or the BE_USER is "admin")
  390. */
  391. function check($type, $value) {
  392. if (isset($this->groupData[$type])) {
  393. if ($this->isAdmin() || $this->inList($this->groupData[$type], $value)) {
  394. return TRUE;
  395. }
  396. }
  397. return FALSE;
  398. }
  399. /**
  400. * Checking the authMode of a select field with authMode set
  401. *
  402. * @param string Table name
  403. * @param string Field name (must be configured in TCA and of type "select" with authMode set!)
  404. * @param string Value to evaluation (single value, must not contain any of the chars ":,|")
  405. * @param string Auth mode keyword (explicitAllow, explicitDeny, individual)
  406. * @return boolean True or false whether access is granted or not.
  407. */
  408. function checkAuthMode($table, $field, $value, $authMode) {
  409. global $TCA;
  410. // Admin users can do anything:
  411. if ($this->isAdmin()) {
  412. return TRUE;
  413. }
  414. // Allow all blank values:
  415. if (!strcmp($value, '')) {
  416. return TRUE;
  417. }
  418. // Certain characters are not allowed in the value
  419. if (preg_match('/[:|,]/', $value)) {
  420. return FALSE;
  421. }
  422. // Initialize:
  423. $testValue = $table . ':' . $field . ':' . $value;
  424. $out = TRUE;
  425. // Checking value:
  426. switch ((string) $authMode) {
  427. case 'explicitAllow':
  428. if (!$this->inList($this->groupData['explicit_allowdeny'], $testValue . ':ALLOW')) {
  429. $out = FALSE;
  430. }
  431. break;
  432. case 'explicitDeny':
  433. if ($this->inList($this->groupData['explicit_allowdeny'], $testValue . ':DENY')) {
  434. $out = FALSE;
  435. }
  436. break;
  437. case 'individual':
  438. t3lib_div::loadTCA($table);
  439. if (is_array($TCA[$table]) && is_array($TCA[$table]['columns'][$field])) {
  440. $items = $TCA[$table]['columns'][$field]['config']['items'];
  441. if (is_array($items)) {
  442. foreach ($items as $iCfg) {
  443. if (!strcmp($iCfg[1], $value) && $iCfg[4]) {
  444. switch ((string) $iCfg[4]) {
  445. case 'EXPL_ALLOW':
  446. if (!$this->inList($this->groupData['explicit_allowdeny'], $testValue . ':ALLOW')) {
  447. $out = FALSE;
  448. }
  449. break;
  450. case 'EXPL_DENY':
  451. if ($this->inList($this->groupData['explicit_allowdeny'], $testValue . ':DENY')) {
  452. $out = FALSE;
  453. }
  454. break;
  455. }
  456. break;
  457. }
  458. }
  459. }
  460. }
  461. break;
  462. }
  463. return $out;
  464. }
  465. /**
  466. * Checking if a language value (-1, 0 and >0 for sys_language records) is allowed to be edited by the user.
  467. *
  468. * @param integer Language value to evaluate
  469. * @return boolean Returns true if the language value is allowed, otherwise false.
  470. */
  471. function checkLanguageAccess($langValue) {
  472. if (strcmp(trim($this->groupData['allowed_languages']), '')) { // The users language list must be non-blank - otherwise all languages are allowed.
  473. $langValue = intval($langValue);
  474. if ($langValue != -1 && !$this->check('allowed_languages', $langValue)) { // Language must either be explicitly allowed OR the lang Value be "-1" (all languages)
  475. return FALSE;
  476. }
  477. }
  478. return TRUE;
  479. }
  480. /**
  481. * Check if user has access to all existing localizations for a certain record
  482. *
  483. * @param string the table
  484. * @param array the current record
  485. * @return boolean
  486. */
  487. function checkFullLanguagesAccess($table, $record) {
  488. $recordLocalizationAccess = $this->checkLanguageAccess(0);
  489. if ($recordLocalizationAccess
  490. && (
  491. t3lib_BEfunc::isTableLocalizable($table)
  492. || isset($GLOBALS['TCA'][$table]['ctrl']['transForeignTable'])
  493. )
  494. ) {
  495. if (isset($GLOBALS['TCA'][$table]['ctrl']['transForeignTable'])) {
  496. $l10nTable = $GLOBALS['TCA'][$table]['ctrl']['transForeignTable'];
  497. $pointerField = $GLOBALS['TCA'][$l10nTable]['ctrl']['transOrigPointerField'];
  498. $pointerValue = $record['uid'];
  499. } else {
  500. $l10nTable = $table;
  501. $pointerField = $GLOBALS['TCA'][$l10nTable]['ctrl']['transOrigPointerField'];
  502. $pointerValue = $record[$pointerField] > 0 ? $record[$pointerField] : $record['uid'];
  503. }
  504. $recordLocalizations = t3lib_BEfunc::getRecordsByField(
  505. $l10nTable,
  506. $pointerField,
  507. $pointerValue,
  508. '',
  509. '',
  510. '',
  511. '1'
  512. );
  513. if (is_array($recordLocalizations)) {
  514. foreach ($recordLocalizations as $localization) {
  515. $recordLocalizationAccess = $recordLocalizationAccess
  516. && $this->checkLanguageAccess($localization[$GLOBALS['TCA'][$l10nTable]['ctrl']['languageField']]);
  517. if (!$recordLocalizationAccess) {
  518. break;
  519. }
  520. }
  521. }
  522. }
  523. return $recordLocalizationAccess;
  524. }
  525. /**
  526. * Checking if a user has editing access to a record from a $TCA table.
  527. * The checks does not take page permissions and other "environmental" things into account. It only deal with record internals; If any values in the record fields disallows it.
  528. * For instance languages settings, authMode selector boxes are evaluated (and maybe more in the future).
  529. * It will check for workspace dependent access.
  530. * The function takes an ID (integer) or row (array) as second argument.
  531. *
  532. * @param string Table name
  533. * @param mixed If integer, then this is the ID of the record. If Array this just represents fields in the record.
  534. * @param boolean Set, if testing a new (non-existing) record array. Will disable certain checks that doesn't make much sense in that context.
  535. * @param boolean Set, if testing a deleted record array.
  536. * @param boolean Set, whenever access to all translations of the record is required
  537. * @return boolean True if OK, otherwise false
  538. */
  539. function recordEditAccessInternals($table, $idOrRow, $newRecord = FALSE, $deletedRecord = FALSE, $checkFullLanguageAccess = FALSE) {
  540. global $TCA;
  541. if (isset($TCA[$table])) {
  542. t3lib_div::loadTCA($table);
  543. // Always return true for Admin users.
  544. if ($this->isAdmin()) {
  545. return TRUE;
  546. }
  547. // Fetching the record if the $idOrRow variable was not an array on input:
  548. if (!is_array($idOrRow)) {
  549. if ($deletedRecord) {
  550. $idOrRow = t3lib_BEfunc::getRecord($table, $idOrRow, '*', '', FALSE);
  551. } else {
  552. $idOrRow = t3lib_BEfunc::getRecord($table, $idOrRow);
  553. }
  554. if (!is_array($idOrRow)) {
  555. $this->errorMsg = 'ERROR: Record could not be fetched.';
  556. return FALSE;
  557. }
  558. }
  559. // Checking languages:
  560. if ($TCA[$table]['ctrl']['languageField']) {
  561. if (isset($idOrRow[$TCA[$table]['ctrl']['languageField']])) { // Language field must be found in input row - otherwise it does not make sense.
  562. if (!$this->checkLanguageAccess($idOrRow[$TCA[$table]['ctrl']['languageField']])) {
  563. $this->errorMsg = 'ERROR: Language was not allowed.';
  564. return FALSE;
  565. } elseif ($checkFullLanguageAccess && $idOrRow[$TCA[$table]['ctrl']['languageField']] == 0 && !$this->checkFullLanguagesAccess($table, $idOrRow)) {
  566. $this->errorMsg = 'ERROR: Related/affected language was not allowed.';
  567. return FALSE;
  568. }
  569. } else {
  570. $this->errorMsg = 'ERROR: The "languageField" field named "' . $TCA[$table]['ctrl']['languageField'] . '" was not found in testing record!';
  571. return FALSE;
  572. }
  573. } elseif (isset($TCA[$table]['ctrl']['transForeignTable']) && $checkFullLanguageAccess && !$this->checkFullLanguagesAccess($table, $idOrRow)) {
  574. return FALSE;
  575. }
  576. // Checking authMode fields:
  577. if (is_array($TCA[$table]['columns'])) {
  578. foreach ($TCA[$table]['columns'] as $fieldName => $fieldValue) {
  579. if (isset($idOrRow[$fieldName])) {
  580. if ($fieldValue['config']['type'] == 'select' && $fieldValue['config']['authMode'] && !strcmp($fieldValue['config']['authMode_enforce'], 'strict')) {
  581. if (!$this->checkAuthMode($table, $fieldName, $idOrRow[$fieldName], $fieldValue['config']['authMode'])) {
  582. $this->errorMsg = 'ERROR: authMode "' . $fieldValue['config']['authMode'] . '" failed for field "' . $fieldName . '" with value "' . $idOrRow[$fieldName] . '" evaluated';
  583. return FALSE;
  584. }
  585. }
  586. }
  587. }
  588. }
  589. // Checking "editlock" feature (doesn't apply to new records)
  590. if (!$newRecord && $TCA[$table]['ctrl']['editlock']) {
  591. if (isset($idOrRow[$TCA[$table]['ctrl']['editlock']])) {
  592. if ($idOrRow[$TCA[$table]['ctrl']['editlock']]) {
  593. $this->errorMsg = 'ERROR: Record was locked for editing. Only admin users can change this state.';
  594. return FALSE;
  595. }
  596. } else {
  597. $this->errorMsg = 'ERROR: The "editLock" field named "' . $TCA[$table]['ctrl']['editlock'] . '" was not found in testing record!';
  598. return FALSE;
  599. }
  600. }
  601. // Checking record permissions
  602. // THIS is where we can include a check for "perms_" fields for other records than pages...
  603. // Process any hooks
  604. if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['recordEditAccessInternals'])) {
  605. foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['recordEditAccessInternals'] as $funcRef) {
  606. $params = array(
  607. 'table' => $table,
  608. 'idOrRow' => $idOrRow,
  609. 'newRecord' => $newRecord
  610. );
  611. if (!t3lib_div::callUserFunction($funcRef, $params, $this)) {
  612. return FALSE;
  613. }
  614. }
  615. }
  616. // Finally, return true if all is well.
  617. return TRUE;
  618. }
  619. }
  620. /**
  621. * Checks a type of permission against the compiled permission integer, $compiledPermissions, and in relation to table, $tableName
  622. *
  623. * @param integer $compiledPermissions could typically be the "compiled permissions" integer returned by ->calcPerms
  624. * @param string $tableName is the tablename to check: If "pages" table then edit,new,delete and editcontent permissions can be checked. Other tables will be checked for "editcontent" only (and $type will be ignored)
  625. * @param string For $tableName='pages' this can be 'edit' (2), 'new' (8 or 16), 'delete' (4), 'editcontent' (16). For all other tables this is ignored. (16 is used)
  626. * @return boolean
  627. * @access public (used by typo3/alt_clickmenu.php)
  628. */
  629. public function isPSet($compiledPermissions, $tableName, $actionType = '') {
  630. if ($this->isAdmin()) {
  631. $result = TRUE;
  632. }
  633. elseif ($tableName == 'pages') {
  634. switch ($actionType) {
  635. case 'edit':
  636. $result = ($compiledPermissions & 2) !== 0;
  637. break;
  638. case 'new':
  639. // Create new page OR page content
  640. $result = ($compiledPermissions & (8 + 16)) !== 0;
  641. break;
  642. case 'delete':
  643. $result = ($compiledPermissions & 4) !== 0;
  644. break;
  645. case 'editcontent':
  646. $result = ($compiledPermissions & 16) !== 0;
  647. break;
  648. default:
  649. $result = FALSE;
  650. }
  651. } else {
  652. $result = ($compiledPermissions & 16) !== 0;
  653. }
  654. return $result;
  655. }
  656. /**
  657. * Returns true if the BE_USER is allowed to *create* shortcuts in the backend modules
  658. *
  659. * @return boolean
  660. */
  661. function mayMakeShortcut() {
  662. // "Shortcuts" have been renamed to "Bookmarks"
  663. // @deprecated remove shortcuts code in TYPO3 4.7
  664. return ($this->getTSConfigVal('options.enableShortcuts')
  665. || $this->getTSConfigVal('options.enableBookmarks'))
  666. && (!$this->getTSConfigVal('options.mayNotCreateEditShortcuts')
  667. && !$this->getTSConfigVal('options.mayNotCreateEditBookmarks'));
  668. }
  669. /**
  670. * Checking if editing of an existing record is allowed in current workspace if that is offline.
  671. * Rules for editing in offline mode:
  672. * - record supports versioning and is an offline version from workspace and has the corrent stage
  673. * - or record (any) is in a branch where there is a page which is a version from the workspace and where the stage is not preventing records
  674. *
  675. * @param string Table of record
  676. * @param array Integer (record uid) or array where fields are at least: pid, t3ver_wsid, t3ver_stage (if versioningWS is set)
  677. * @return string String error code, telling the failure state. FALSE=All ok
  678. */
  679. function workspaceCannotEditRecord($table, $recData) {
  680. if ($this->workspace !== 0) { // Only test offline spaces:
  681. if (!is_array($recData)) {
  682. $recData = t3lib_BEfunc::getRecord($table, $recData, 'pid' . ($GLOBALS['TCA'][$table]['ctrl']['versioningWS'] ? ',t3ver_wsid,t3ver_stage' : ''));
  683. }
  684. if (is_array($recData)) {
  685. if ((int) $recData['pid'] === -1) { // We are testing a "version" (identified by a pid of -1): it can be edited provided that workspace matches and versioning is enabled for the table.
  686. if (!$GLOBALS['TCA'][$table]['ctrl']['versioningWS']) { // No versioning, basic error, inconsistency even! Such records should not have a pid of -1!
  687. return 'Versioning disabled for table';
  688. } elseif ((int) $recData['t3ver_wsid'] !== $this->workspace) { // So does workspace match?
  689. return 'Workspace ID of record didn\'t match current workspace';
  690. } else { // So what about the stage of the version, does that allow editing for this user?
  691. return $this->workspaceCheckStageForCurrent($recData['t3ver_stage']) ? FALSE : 'Record stage "' . $recData['t3ver_stage'] . '" and users access level did not allow for editing';
  692. }
  693. } else { // We are testing a "live" record:
  694. if ($res = $this->workspaceAllowLiveRecordsInPID($recData['pid'], $table)) { // For "Live" records, check that PID for table allows editing
  695. // Live records are OK in this branch, but what about the stage of branch point, if any:
  696. return $res > 0 ? FALSE : 'Stage for versioning root point and users access level did not allow for editing'; // OK
  697. } else { // If not offline and not in versionized branch, output error:
  698. return 'Online record was not in versionized branch!';
  699. }
  700. }
  701. } else {
  702. return 'No record';
  703. }
  704. } else {
  705. return FALSE; // OK because workspace is 0
  706. }
  707. }
  708. /**
  709. * Evaluates if a user is allowed to edit the offline version
  710. *
  711. * @param string Table of record
  712. * @param array Integer (record uid) or array where fields are at least: pid, t3ver_wsid, t3ver_stage (if versioningWS is set)
  713. * @return string String error code, telling the failure state. FALSE=All ok
  714. * @see workspaceCannotEditRecord()
  715. */
  716. function workspaceCannotEditOfflineVersion($table, $recData) {
  717. if ($GLOBALS['TCA'][$table]['ctrl']['versioningWS']) {
  718. if (!is_array($recData)) {
  719. $recData = t3lib_BEfunc::getRecord($table, $recData, 'uid,pid,t3ver_wsid,t3ver_stage');
  720. }
  721. if (is_array($recData)) {
  722. if ((int) $recData['pid'] === -1) {
  723. return $this->workspaceCannotEditRecord($table, $recData);
  724. } else {
  725. return 'Not an offline version';
  726. }
  727. } else {
  728. return 'No record';
  729. }
  730. } else {
  731. return 'Table does not support versioning.';
  732. }
  733. }
  734. /**
  735. * Check if "live" records from $table may be created or edited in this PID.
  736. * If the answer is FALSE it means the only valid way to create or edit records in the PID is by versioning
  737. * If the answer is 1 or 2 it means it is OK to create a record, if -1 it means that it is OK in terms of versioning because the element was within a versionized branch but NOT ok in terms of the state the root point had!
  738. *
  739. * @param integer PID value to check for.
  740. * @param string Table name
  741. * @return mixed Returns FALSE if a live record cannot be created and must be versionized in order to do so. 2 means a) Workspace is "Live" or workspace allows "live edit" of records from non-versionized tables (and the $table is not versionizable). 1 and -1 means the pid is inside a versionized branch where -1 means that the branch-point did NOT allow a new record according to its state.
  742. */
  743. function workspaceAllowLiveRecordsInPID($pid, $table) {
  744. // Always for Live workspace AND if live-edit is enabled and tables are completely without versioning it is ok as well.
  745. if ($this->workspace === 0 || ($this->workspaceRec['live_edit'] && !$GLOBALS['TCA'][$table]['ctrl']['versioningWS']) || $GLOBALS['TCA'][$table]['ctrl']['versioningWS_alwaysAllowLiveEdit']) {
  746. return 2; // OK to create for this table.
  747. } elseif (t3lib_BEfunc::isPidInVersionizedBranch($pid, $table)) { // Check if records from $table can be created with this PID: Either if inside "branch" versioning type or a "versioning_followPages" table on a "page" versioning type.
  748. // Now, check what the stage of that "page" or "branch" version type is:
  749. $stage = t3lib_BEfunc::isPidInVersionizedBranch($pid, $table, TRUE);
  750. return $this->workspaceCheckStageForCurrent($stage) ? 1 : -1;
  751. } else {
  752. return FALSE; // If the answer is FALSE it means the only valid way to create or edit records in the PID is by versioning
  753. }
  754. }
  755. /**
  756. * Evaluates if a record from $table can be created in $pid
  757. *
  758. * @param integer Page id. This value must be the _ORIG_uid if available: So when you have pages versionized as "page" or "element" you must supply the id of the page version in the workspace!
  759. * @param string Table name
  760. * @return boolean TRUE if OK.
  761. */
  762. function workspaceCreateNewRecord($pid, $table) {
  763. if ($res = $this->workspaceAllowLiveRecordsInPID($pid, $table)) { // If LIVE records cannot be created in the current PID due to workspace restrictions, prepare creation of placeholder-record
  764. if ($res < 0) {
  765. return FALSE; // Stage for versioning root point and users access level did not allow for editing
  766. }
  767. } elseif (!$GLOBALS['TCA'][$table]['ctrl']['versioningWS']) { // So, if no live records were allowed, we have to create a new version of this record:
  768. return FALSE;
  769. }
  770. return TRUE;
  771. }
  772. /**
  773. * Evaluates if auto creation of a version of a record is allowed.
  774. *
  775. * @param string Table of the record
  776. * @param integer UID of record
  777. * @param integer PID of record
  778. * @return boolean TRUE if ok.
  779. */
  780. function workspaceAllowAutoCreation($table, $id, $recpid) {
  781. // Auto-creation of version: In offline workspace, test if versioning is enabled and look for workspace version of input record. If there is no versionized record found we will create one and save to that.
  782. if ($this->workspace !== 0 // Only in draft workspaces
  783. && !$this->workspaceRec['disable_autocreate'] // Auto-creation must not be disabled.
  784. && $GLOBALS['TCA'][$table]['ctrl']['versioningWS'] // Table must be versionizable
  785. && $recpid >= 0 // The PID of the record must NOT be -1 or less (would indicate that it already was a version!)
  786. && !t3lib_BEfunc::getWorkspaceVersionOfRecord($this->workspace, $table, $id, 'uid') // There must be no existing version of this record in workspace.
  787. && !t3lib_BEfunc::isPidInVersionizedBranch($recpid, $table)) { // PID must NOT be in a versionized branch either
  788. return TRUE;
  789. } else if ($this->workspaceRec['disable_autocreate']) {
  790. t3lib_div::deprecationLog('Usage of disable_autocreate feature is deprecated since 4.5.');
  791. }
  792. }
  793. /**
  794. * Checks if an element stage allows access for the user in the current workspace
  795. * In workspaces 0 (Live) and -1 (Default draft) access is always granted for any stage.
  796. * Admins are always allowed.
  797. * An option for custom workspaces allows members to also edit when the stage is "Review"
  798. *
  799. * @param integer Stage id from an element: -1,0 = editing, 1 = reviewer, >1 = owner
  800. * @return boolean TRUE if user is allowed access
  801. */
  802. function workspaceCheckStageForCurrent($stage) {
  803. $stage = intval($stage);
  804. if ($this->isAdmin()) {
  805. return TRUE;
  806. }
  807. if ($this->workspace > 0 && t3lib_extMgm::isLoaded('workspaces')) {
  808. $stat = $this->checkWorkspaceCurrent();
  809. // Check if custom staging is activated
  810. $workspaceRec = t3lib_BEfunc::getRecord('sys_workspace', $stat['uid']);
  811. if ($workspaceRec['custom_stages'] > 0 && $stage !== 0 && $stage !== '-10') {
  812. // Get custom stage record
  813. $workspaceStageRec = t3lib_BEfunc::getRecord('sys_workspace_stage', $stage);
  814. // Check if the user is responsible for the current stage
  815. if ((t3lib_div::inList($workspaceStageRec['responsible_persons'], 'be_users_' . $this->user['uid'])
  816. && $stat['_ACCESS'] === 'member')
  817. || $stat['_ACCESS'] === 'owner') {
  818. return TRUE;
  819. }
  820. // Check if the user is in a group which is responsible for the current stage
  821. foreach ($this->userGroupsUID as $groupUid) {
  822. if ((t3lib_div::inList($workspaceStageRec['responsible_persons'], 'be_groups_' . $groupUid)
  823. && $stat['_ACCESS'] === 'member')
  824. || $stat['_ACCESS'] === 'owner') {
  825. return TRUE;
  826. }
  827. }
  828. // only owner is allowed to change records which are "ready to publish"
  829. } elseif ($stage == '-10' || $stage == '-20') {
  830. if ($stat['_ACCESS'] === 'owner') {
  831. return TRUE;
  832. } else {
  833. return FALSE;
  834. }
  835. } else {
  836. $memberStageLimit = $this->workspaceRec['review_stage_edit'] ? 1 : 0;
  837. if (($stage <= $memberStageLimit && $stat['_ACCESS'] === 'member')
  838. || ($stage <= 1 && $stat['_ACCESS'] === 'reviewer')
  839. || $stat['_ACCESS'] === 'owner') {
  840. return TRUE;
  841. }
  842. }
  843. } else {
  844. return TRUE;
  845. } // Always OK for live and draft workspaces.
  846. }
  847. /**
  848. * Returns TRUE if the user has access to publish content from the workspace ID given.
  849. * Admin-users are always granted access to do this
  850. * If the workspace ID is 0 (live) all users have access also
  851. * If -1 (draft workspace) TRUE is returned if the user has access to the Live workspace
  852. * For custom workspaces it depends on whether the user is owner OR like with draft workspace if the user has access to Live workspace.
  853. *
  854. * @param integer Workspace UID; -1,0,1+
  855. * @return boolean Returns TRUE if the user has access to publish content from the workspace ID given.
  856. */
  857. function workspacePublishAccess($wsid) {
  858. if ($this->isAdmin()) {
  859. return TRUE;
  860. }
  861. // If no access to workspace, of course you cannot publish!
  862. $retVal = FALSE;
  863. $wsAccess = $this->checkWorkspace($wsid);
  864. if ($wsAccess) {
  865. switch ($wsAccess['uid']) {
  866. case 0: // Live workspace
  867. $retVal = TRUE; // If access to Live workspace, no problem.
  868. break;
  869. case -1: // Default draft workspace
  870. $retVal = $this->checkWorkspace(0) ? TRUE : FALSE; // If access to Live workspace, no problem.
  871. break;
  872. default: // Custom workspace
  873. $retVal = $wsAccess['_ACCESS'] === 'owner' || ($this->checkWorkspace(0) && !($wsAccess['publish_access'] & 2)); // Either be an adminuser OR have access to online workspace which is OK as well as long as publishing access is not limited by workspace option.
  874. break;
  875. }
  876. }
  877. return $retVal;
  878. }
  879. /**
  880. * Workspace swap-mode access?
  881. *
  882. * @return boolean Returns TRUE if records can be swapped in the current workspace, otherwise false
  883. */
  884. function workspaceSwapAccess() {
  885. if ($this->workspace > 0 && (int) $this->workspaceRec['swap_modes'] === 2) {
  886. return FALSE;
  887. } else {
  888. return TRUE;
  889. }
  890. }
  891. /**
  892. * Workspace Versioning type access. Check wether the requsted type of versioning (element/page/branch) is allowd in current workspace
  893. * (element/pages/branches type of versioning can/could be set on custom workspaces on filed "vtype")
  894. *
  895. * @todo workspacecleanup: this seems mostly obsolete and should be removed
  896. * @param integer Versioning type to evaluation: -1, 0, >1
  897. * 0 = page (deprecated)
  898. * -1 = element
  899. * >1 = branch (deprecated), indicating the "nesting" level
  900. * @return boolean TRUE if OK
  901. */
  902. function workspaceVersioningTypeAccess($type) {
  903. $retVal = FALSE;
  904. $type = t3lib_div::intInRange($type, -1);
  905. // Check if only element versioning is allowed:
  906. if ($GLOBALS['TYPO3_CONF_VARS']['BE']['elementVersioningOnly'] && $type != -1) {
  907. return FALSE;
  908. }
  909. if ($this->workspace > 0 && !$this->isAdmin()) {
  910. $stat = $this->checkWorkspaceCurrent();
  911. if ($stat['_ACCESS'] !== 'owner') {
  912. switch ((int) $type) {
  913. case -1:
  914. $retVal = $this->workspaceRec['vtypes'] & 1 ? FALSE : TRUE;
  915. break;
  916. case 0:
  917. $retVal = $this->workspaceRec['vtypes'] & 2 ? FALSE : TRUE;
  918. break;
  919. default:
  920. $retVal = $this->workspaceRec['vtypes'] & 4 ? FALSE : TRUE;
  921. break;
  922. }
  923. } else {
  924. $retVal = TRUE;
  925. }
  926. } else {
  927. $retVal = TRUE;
  928. }
  929. return $retVal;
  930. }
  931. /**
  932. * Finding "closest" versioning type, used for creation of new records.
  933. *
  934. * @see workspaceVersioningTypeAccess() for hints on $type
  935. * @param integer Versioning type to evaluation: -1, 0, >1
  936. * @return integer Returning versioning type
  937. */
  938. function workspaceVersioningTypeGetClosest($type) {
  939. $type = t3lib_div::intInRange($type, -1);
  940. if ($this->workspace > 0) {
  941. switch ((int) $type) {
  942. case -1:
  943. $type = -1;
  944. break;
  945. case 0:
  946. $type = $this->workspaceVersioningTypeAccess($type) ? $type : -1;
  947. break;
  948. default:
  949. $type = $this->workspaceVersioningTypeAccess($type) ? $type : ($this->workspaceVersioningTypeAccess(0) ? 0 : -1);
  950. break;
  951. }
  952. }
  953. return $type;
  954. }
  955. /*************************************
  956. *
  957. * Miscellaneous functions
  958. *
  959. *************************************/
  960. /**
  961. * Returns the value/properties of a TS-object as given by $objectString, eg. 'options.dontMountAdminMounts'
  962. * Nice (general!) function for returning a part of a TypoScript array!
  963. *
  964. * @param string Pointer to an "object" in the TypoScript array, fx. 'options.dontMountAdminMounts'
  965. * @param array Optional TSconfig array: If array, then this is used and not $this->userTS. If not array, $this->userTS is used.
  966. * @return array An array with two keys, "value" and "properties" where "value" is a string with the value of the objectsting and "properties" is an array with the properties of the objectstring.
  967. * @params array An array with the TypoScript where the $objectString is located. If this argument is not an array, then internal ->userTS (User TSconfig for the current BE_USER) will be used instead.
  968. */
  969. function getTSConfig($objectString, $config = '') {
  970. if (!is_array($config)) {
  971. $config = $this->userTS; // Getting Root-ts if not sent
  972. }
  973. $TSConf = array();
  974. $parts = explode('.', $objectString, 2);
  975. $key = $parts[0];
  976. if (trim($key)) {
  977. if (count($parts) > 1 && trim($parts[1])) {
  978. // Go on, get the next level
  979. if (is_array($config[$key . '.'])) {
  980. $TSConf = $this->getTSConfig($parts[1], $config[$key . '.']);
  981. }
  982. } else {
  983. $TSConf['value'] = $config[$key];
  984. $TSConf['properties'] = $config[$key . '.'];
  985. }
  986. }
  987. return $TSConf;
  988. }
  989. /**
  990. * Returns the "value" of the $objectString from the BE_USERS "User TSconfig" array
  991. *
  992. * @param string Object string, eg. "somestring.someproperty.somesubproperty"
  993. * @return string The value for that object string (object path)
  994. * @see getTSConfig()
  995. */
  996. function getTSConfigVal($objectString) {
  997. $TSConf = $this->getTSConfig($objectString);
  998. return $TSConf['value'];
  999. }
  1000. /**
  1001. * Returns the "properties" of the $objectString from the BE_USERS "User TSconfig" array
  1002. *
  1003. * @param string Object string, eg. "somestring.someproperty.somesubproperty"
  1004. * @return array The properties for that object string (object path) - if any
  1005. * @see getTSConfig()
  1006. */
  1007. function getTSConfigProp($objectString) {
  1008. $TSConf = $this->getTSConfig($objectString);
  1009. return $TSConf['properties'];
  1010. }
  1011. /**
  1012. * Returns true if $item is in $in_list
  1013. *
  1014. * @param string Comma list with items, no spaces between items!
  1015. * @param string The string to find in the list of items
  1016. * @return string Boolean
  1017. */
  1018. function inList($in_list, $item) {
  1019. return strstr(',' . $in_list . ',', ',' . $item . ',');
  1020. }
  1021. /**
  1022. * Returns an array with the webmounts.
  1023. * If no webmounts, and empty array is returned.
  1024. * NOTICE: Deleted pages WILL NOT be filtered out! So if a mounted page has been deleted it is STILL coming out as a webmount. This is not checked due to performance.
  1025. *
  1026. * @return array
  1027. */
  1028. function returnWebmounts() {
  1029. return (string) ($this->groupData['webmounts']) != '' ? explode(',', $this->groupData['webmounts']) : array();
  1030. }
  1031. /**
  1032. * Returns an array with the filemounts for the user. Each filemount is represented with an array of a "name", "path" and "type".
  1033. * If no filemounts an empty array is returned.
  1034. *
  1035. * @return array
  1036. */
  1037. function returnFilemounts() {
  1038. return $this->groupData['filemounts'];
  1039. }
  1040. /**
  1041. * Returns an integer bitmask that represents the permissions for file operations.
  1042. * Permissions of the user and groups the user is a member of were combined by a logical OR.
  1043. *
  1044. * Meaning of each bit:
  1045. * 1 - Files: Upload,Copy,Move,Delete,Rename
  1046. * 2 - Files: Unzip
  1047. * 4 - Directory: Move,Delete,Rename,New
  1048. * 8 - Directory: Copy
  1049. * 16 - Directory: Delete recursively (rm -Rf)
  1050. *
  1051. * @return integer File operation permission bitmask
  1052. */
  1053. public function getFileoperationPermissions() {
  1054. if ($this->isAdmin()) {
  1055. return 31;
  1056. } else {
  1057. return $this->groupData['fileoper_perms'];
  1058. }
  1059. }
  1060. /**
  1061. * Returns true or false, depending if an alert popup (a javascript confirmation) should be shown
  1062. * call like $GLOBALS['BE_USER']->jsConfirmation($BITMASK)
  1063. *
  1064. * 1 - typeChange
  1065. * 2 - copy/move/paste
  1066. * 4 - delete
  1067. * 8 - frontend editing
  1068. * 128 - other (not used yet)
  1069. *
  1070. * @param integer Bitmask
  1071. * @return boolean true if the confirmation should be shown
  1072. */
  1073. function jsConfirmation($bitmask) {
  1074. $alertPopup = $GLOBALS['BE_USER']->getTSConfig('options.alertPopups');
  1075. if (empty($alertPopup['value'])) {
  1076. $alertPopup = 255; // default: show all warnings
  1077. } else {
  1078. $alertPopup = (int) $alertPopup['value'];
  1079. }
  1080. if (($alertPopup & $bitmask) == $bitmask) { // show confirmation
  1081. return 1;
  1082. } else { // don't show confirmation
  1083. return 0;
  1084. }
  1085. }
  1086. /*************************************
  1087. *
  1088. * Authentication methods
  1089. *
  1090. *************************************/
  1091. /**
  1092. * Initializes a lot of stuff like the access-lists, database-mountpoints and filemountpoints
  1093. * This method is called by ->backendCheckLogin() (from extending class t3lib_beuserauth) if the backend user login has verified OK.
  1094. * Generally this is required initialization of a backend user.
  1095. *
  1096. * @return void
  1097. * @access private
  1098. * @see t3lib_TSparser
  1099. */
  1100. function fetchGroupData() {
  1101. if ($this->user['uid']) {
  1102. // Get lists for the be_user record and set them as default/primary values.
  1103. $this->dataLists['modList'] = $this->user['userMods']; // Enabled Backend Modules
  1104. $this->dataLists['allowed_languages'] = $this->user['allowed_languages']; // Add Allowed Languages
  1105. $this->dataLists['workspace_perms'] = $this->user['workspace_perms']; // Set user value for workspace permissions.
  1106. $this->dataLists['webmount_list'] = $this->user['db_mountpoints']; // Database mountpoints
  1107. $this->dataLists['filemount_list'] = $this->user['file_mountpoints']; // File mountpoints
  1108. $this->dataLists['fileoper_perms'] = (int) $this->user['fileoper_perms']; // Fileoperation permissions
  1109. // Setting default User TSconfig:
  1110. $this->TSdataArray[] = $this->addTScomment('From $GLOBALS["TYPO3_CONF_VARS"]["BE"]["defaultUserTSconfig"]:') .
  1111. $GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'];
  1112. // Default TSconfig for admin-users
  1113. if ($this->isAdmin()) {
  1114. $this->TSdataArray[] = $this->addTScomment('"admin" user presets:') . '
  1115. admPanel.enable.all = 1
  1116. ';
  1117. if (t3lib_extMgm::isLoaded('sys_note')) {
  1118. $this->TSdataArray[] = '
  1119. // Setting defaults for sys_note author / email...
  1120. TCAdefaults.sys_note.author = ' . $this->user['realName'] . '
  1121. TCAdefaults.sys_note.email = ' . $this->user['email'] . '
  1122. ';
  1123. }
  1124. }
  1125. // FILE MOUNTS:
  1126. // Admin users has the base fileadmin dir mounted
  1127. if ($this->isAdmin() && $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir']) {
  1128. $this->addFileMount($GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'], '', PATH_site . $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'], 0, '');
  1129. }
  1130. // If userHomePath is set, we attempt to mount it
  1131. if ($GLOBALS['TYPO3_CONF_VARS']['BE']['userHomePath']) {
  1132. // First try and mount with [uid]_[username]
  1133. $didMount = $this->addFileMount($this->user['username'], '', $GLOBALS['TYPO3_CONF_VARS']['BE']['userHomePath'] . $this->user['uid'] . '_' . $this->user['username'] . $GLOBALS['TYPO3_CONF_VARS']['BE']['userUploadDir'], 0, 'user');
  1134. if (!$didMount) {
  1135. // If that failed, try and mount with only [uid]
  1136. $this->addFileMount($this->user['username'], '', $GLOBALS['TYPO3_CONF_VARS']['BE']['userHomePath'] . $this->user['uid'] . $GLOBALS['TYPO3_CONF_VARS']['BE']['userUploadDir'], 0, 'user');
  1137. }
  1138. }
  1139. // BE_GROUPS:
  1140. // Get the groups...
  1141. #

Large files files are truncated, but you can click here to view the full file