Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
page_account_manager.inc
1 <?php
18 require_once dirname(__FILE__).'/../../page_templates/page_asset_builder/page_asset_builder.inc';
19 require_once SQ_FUDGE_PATH.'/general/text.inc';
20 require_once SQ_LIB_PATH.'/html_form/html_form.inc';
21 
34 {
35 
36 
43  function __construct($assetid=0)
44  {
45  parent::__construct($assetid);
46 
47  }//end constructor
48 
49 
64  function create(&$link)
65  {
66  // Set default value for validation email format attr
67  $val = Array();
68  $val['subject'] = translate('cms_account_manager_validation_email_default_subject');
69  $val['text_format'] = translate('cms_account_manager_validation_email_default_content', '%validation_url%');
70  $val['html_format'] = '<p>'.translate('cms_account_manager_validation_email_default_content', '<a href="%validation_url%">%validation_url%</a>').'</p>';
71  $val['from'] = SQ_CONF_SYSTEM_NAME.' <'.SQ_CONF_DEFAULT_EMAIL.'>';
72  $this->setAttrVAlue('validation_email_format', $val);
73 
74  return parent::create($link);
75 
76  }//end create()
77 
78 
89  function saveAttributes($dont_run_updated=FALSE)
90  {
91  if (isset($this->_tmp['vars_set']['use_email_validation'])) {
92  if ($this->attr('use_email_validation')) {
93  $new_names = Array(
94  'create_no_login' => translate('cms_account_manager_awaiting_validation'),
95  'create_login' => translate ('cms_account_manager_validated'),
96  );
97  } else {
98  $new_names = Array(
99  'create_no_login' => translate('cms_account_manager_created_not_live'),
100  'create_login' => translate('cms_account_manager_created_live'),
101  );
102  }
103  foreach (Array('create_login', 'create_no_login') as $value) {
104  $link = $GLOBALS['SQ_SYSTEM']->am->getLink($this->id, NULL, 'bodycopy', TRUE, $value);
105  if (!empty($link)) {
106  $bc = $GLOBALS['SQ_SYSTEM']->am->getAsset($link['minorid'], 'bodycopy');
107  $bc->setAttrValue('name', $new_names[$value]);
108  $bc->saveAttributes();
109  }
110  }
111  }
112 
113  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
114  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
115 
116  // if we are using email validation - ensure that the username and email attributes are required fields
117  if ($this->attr('use_email_validation')) {
118 
119  $required_fields = $this->attr('required_fields');
120  list($create_type) = array_keys($this->attr('create_type'));
121  $save = FALSE;
122  if (!isset($required_fields[$create_type])) {
123  $required_fields[$create_type] = Array();
124  }
125  if (!isset($required_fields[$create_type]['username'])) {
126  $required_fields[$create_type]['username'] = translate('cms_account_manager_username_required');
127  $save = TRUE;
128  }
129  if (!isset($required_fields[$create_type]['email'])) {
130  $required_fields[$create_type]['email'] = translate('cms_account_manager_email_required');
131  $save = TRUE;
132  }
133 
134  if ($save) {
135  if (!$this->setAttrValue('required_fields', $required_fields)) {
136  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
137  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
138  return FALSE;
139  }// end if
140  }// en dif
141 
142  }// end if
143 
144  if (!parent::saveAttributes($dont_run_updated)) {
145  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
146  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
147  return FALSE;
148  }
149 
150  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
151  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
152  return TRUE;
153 
154  }//end saveAttributes()
155 
156 
163  function printFrontend()
164  {
165  $current_user = $GLOBALS['SQ_SYSTEM']->user;
166  if ((!is_null($current_user) && !($current_user instanceof Public_User)) && !SQ_IN_LIMBO) {
167 
168  if ($this->attr('enter_edit_mode')) {
169  // this person is logged in - so redirect them to limbo where they can edit their details
170  $redirect_url = strip_url($this->getURL()).'/'.SQ_CONF_LIMBO_SUFFIX.'/?ignore_frames=1';
171  }
172 
173  // BUT if they have just logged in via this page we might want to redirect them somewhere else...
174  if (isset($_REQUEST['SQ_LOGIN_ACCOUNT_MANAGER_STATE']) && $_REQUEST['SQ_LOGIN_ACCOUNT_MANAGER_STATE'] == 'create_login') {
175  $link = $GLOBALS['SQ_SYSTEM']->am->getLink($this->id, SQ_LINK_NOTICE, '', FALSE, 'login_redirect');
176  if (!empty($link)) {
177  // the manager is configured with a custom redirect location
178  $redirect_asset = $GLOBALS['SQ_SYSTEM']->am->getAsset($link['minorid']);
179  $redirect_url = $redirect_asset->getURL();
180  $GLOBALS['SQ_SYSTEM']->am->forgetAsset($redirect_asset);
181  }//end if
182  }//end if
183  } //end if
184 
185  if (isset($redirect_url)) {
186  header('Location: '.$redirect_url);
187  exit();
188  } else {
189  parent::printFrontend();
190  }
191 
192  }//end printFrontend()
193 
194 
202  {
203  $this->_replacements['resend_validation_form'] = $this->getkeywordreplacement('re_send_validation_form');
204  parent::_loadCreateReplacements();
205 
206  }//end _loadCreateReplacements()
207 
208 
219  function initLimbo()
220  {
221  // intentonally blank
222 
223  }//end initLimbo()
224 
225 
232  function printLimbo()
233  {
234  // if there is no backend outputter object it is likely we are using a login design
235  // the backend outputter will be present however when the user logs in
236  if (isset($GLOBALS['SQ_SYSTEM']->backend->out)) {
237  $GLOBALS['SQ_SYSTEM']->backend->out->addFormActionGetVar('ignore_frames', '1', TRUE);
238  }
239 
240  $current_user = $GLOBALS['SQ_SYSTEM']->user;
241  $this->_current_state = 'logged_in';
242 
243  if (!is_null($current_user) && !($current_user instanceof Public_User)) {
244  // try and acquire a lock on the current user so they can edit their details
245  $hh = $GLOBALS['SQ_SYSTEM']->getHipoHerder();
246  $vars = Array(
247  'assetids' => Array($current_user->id,),
248  'lock_type' => 'attributes',
249  'forceably_acquire' => FALSE,
250  );
251  $lock_errors = $hh->freestyleHipo('hipo_job_acquire_locks', $vars);
252 
253 
255  // EDIT DETAILS FORM //
257  ob_start();
258 
259  if (!empty($lock_errors)) {
260  $this->_replacements['edit_details_lock_error'] = $this->getKeywordReplacement('edit_details_lock_error');
261  $current_user->printBody();
262  } else {
263 
264 
265  // ensure that the user has access to edit their details
266  // ie. they have permission to access the default screen for a user
267  require_once SQ_INCLUDE_PATH.'/asset_edit_interface.inc';
268  $aei = new Asset_Edit_Interface($current_user->type());
269 
270  $allowed_screens = $aei->getAllowedScreens($current_user);
271  $default_screen = $aei->_default_screen;
272  if (empty($default_screen)) {
273  $default_screen = 'details';
274  }
275 
276  $check_screen_restrictions = (!($GLOBALS['SQ_SYSTEM']->userRoot() || $GLOBALS['SQ_SYSTEM']->userSystemAdmin()));
277  if ($check_screen_restrictions) {
278  if (empty($allowed_screens)) {
279  $check_screen_restrictions = FALSE;
280  }
281  }
282 
283  if ($check_screen_restrictions && !isset($allowed_screens[$default_screen])) {
284  $this->_replacements['edit_details_invite'] = '<p>'.translate('cms_account_manager_cannot_edit_details').'</p>';
285  $current_user->printBody();
286  } else {
287  $this->_replacements['edit_details_invite'] = $this->attr('edit_details_invite');
288  $current_user->initLimbo();
289  $current_user->printLimbo();
290  }
291  unset($aei);
292  }
293  $this->_replacements['edit_details_form'] = ob_get_contents();
294  ob_end_clean();
295 
296 
298  // LOG OUT FORM //
300  $this->_replacements['logout_form'] = $this->getKeywordReplacement('logout_form');
301  }//end if
302  $this->_printContents();
303 
304  }//end printLimbo()
305 
306 
314  function _getAllowedLinks()
315  {
316  $allowed = parent::_getAllowedLinks();
317  $allowed[SQ_LINK_NOTICE]['asset'] = Array('card' => 'M', 'exclusive' => FALSE);
318 
319  return $allowed;
320 
321  }//end _getAllowedLinks()
322 
323 
335  {
336  list($create_type) = array_keys($this->attr('create_type'));
337 
338  // resend validation email form was submitted?
339 
340  if (isset($_POST['AB_'.$this->id.'_ASSET_BUILDER_ACTION']) && $_POST['AB_'.$this->id.'_ASSET_BUILDER_ACTION'] == 'resend_validation') {
341  return $this->resendValidation();
342  }
343 
344  if (strtolower(array_get_index($_GET, 'action', '')) == 'validate') {
345  // grab the user and create locations
346  $user = $this->_getCurrentPendingUser();
347  if (!is_null($user)) {
348 
349  if ($this->validateUser($user)) {
350  $this->_current_state = 'create_login';
351  $_POST['SQ_LOGIN_USERNAME'] = $user->attr('username');
352  $this->_replacements['login_invite'] = $this->attr('login_invite');
353  $this->_replacements['login_form'] = $this->getKeywordReplacement('login_form');
354  $GLOBALS['SQ_SYSTEM']->am->forgetAsset($user);
355  return TRUE;
356  }
357  return FALSE;
358 
359  }//end if
360  }//end if action is validate
361 
362  // additional checks if we are using email validation
363  if ($this->attr('use_email_validation') && isset($_POST['AB_'.$this->id.'_ASSET_BUILDER_ACTION']) && strtolower($_POST['AB_'.$this->id.'_ASSET_BUILDER_ACTION']) == 'create') {
364 
365  // create the unique ID we will use to identify this new user if it gets created
366  $this->_tmp['am_created_asset_key'] = '';
367 
368  $GLOBALS['SQ_SYSTEM']->am->includeAsset($create_type);
369  $new_asset = new $create_type();
370 
371  $real_username = $new_asset->getAttribute('username', TRUE);
372  if (is_null($real_username)) continue;
373  // take a copy of the username so we don't muck anything up for the processBackend() (if we get that far;)
374  $username = $real_username;
375 
376  $username->process($new_asset->getPrefix().'_'.$username->id);
377  if ($username->processed) {
378  if (!empty($username->value)) {
379  $this->_tmp['am_created_asset_key'] = md5(microtime().$username->value);
380  }
381  }
382 
383  unset($real_username);
384  unset($username);
385 
386  }//end if using email validation
387 
388  // get asset_builder to create the asset, but since we have overridden
389  // getCreateLocations it will only go into our pending accounts group
390  // if email verification is enabled.
391 
392  $success = parent::_processGlobalActions();
393  if (!$success) return FALSE;
394 
395  if (isset($_POST['AB_'.$this->id.'_ASSET_BUILDER_ACTION'])) {
396  switch (strtolower($_POST['AB_'.$this->id.'_ASSET_BUILDER_ACTION'])) {
397  case 'create' :
398  if (empty($this->_errors) && !empty($this->_tmp['created_asset'])) {
399  if ($this->attr('use_email_validation')) {
400  // notice link the newly-created asset underneath the selected create locations,
401  // so when we validate we know which create locations were selected
402  $new_asset =& $this->_tmp['created_asset'];
403 
404  // Remove all permission from the created user, apart from the admin permission the
405  // user is allowed to hold on itself. This means the user will not inherit permissions
406  // from the Pending Accounts folder.
407  $GLOBALS['SQ_SYSTEM']->setRunLevel(SQ_RUN_LEVEL_FORCED);
408 
409  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
410  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
411 
412  foreach (get_constant_values('SQ_PERMISSION_') as $permission_name => $permission) {
413  $permissions = $GLOBALS['SQ_SYSTEM']->am->getPermission($new_asset->id, $permission, NULL, FALSE);
414  foreach ($permissions as $userid) {
415  if (!(($permission == SQ_PERMISSION_ADMIN) && ($userid == $new_asset->id))) {
416  if (!$GLOBALS['SQ_SYSTEM']->am->deletePermission($new_asset->id, $userid, $permission)) {
417  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
418  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
419  $GLOBALS['SQ_SYSTEM']->restoreRunLevel();
420  return FALSE;
421  }
422  }
423  }
424  $permissions = $GLOBALS['SQ_SYSTEM']->am->getPermission($new_asset->id, $permission, NULL, FALSE);
425  }
426 
427  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
428  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
429  $GLOBALS['SQ_SYSTEM']->restoreRunLevel();
430 
431  // manually parse the create locations, format into an array in the format Array(locationid => Array('name'=>code_name, 'link_type'=>link_type), ...)
432  $selected_create_locations = Array();
433  foreach ($this->attr('create_location_optional') as $set_name => $details) {
434  $tmp_locations = Array();
435  $code_name = $this->_sanitiseLocationSetName($set_name);
436  if (isset($_POST[$code_name])) {
437  if ($details['allow_multiple'] && is_array($_POST[$code_name])) {
438  foreach ($_POST[$code_name] as $location_id) {
439  // add it to the list
440  $tmp_locations[] = $location_id;
441  }
442  // check the list options are valid
443  $tmp_locations = array_intersect($tmp_locations, array_keys($details['locations']));
444  // add them to the collection
445  foreach ($tmp_locations as $location_id) {
446  $selected_create_locations[$location_id] = Array(
447  'set_name' => $set_name,
448  'link_type' => (int)$details['link_type'],
449  );
450  }
451  } else {
452  // if it's valid, add it to the list
453  if (in_array($_POST[$code_name], array_keys($details['locations']))) {
454  $selected_create_locations[(int)$_POST[$code_name]] = Array(
455  'set_name' => $set_name,
456  'link_type' => (int)$details['link_type'],
457  );
458  }
459  }
460  } else if (!$details['allow_empty']) {
461  trigger_localised_error('CMS0036', E_USER_WARNING, $set_name);
462  return FALSE;
463  }
464  }
465 
466 
467  // use the formatted array, create the notice links
468  if (!empty($selected_create_locations)) {
469  $GLOBALS['SQ_SYSTEM']->setRunLevel(SQ_RUN_LEVEL_FORCED);
470 
471  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
472  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
473 
474  foreach ($selected_create_locations as $locationid => $link_type) {
475  $location = $GLOBALS['SQ_SYSTEM']->am->getAsset($locationid, '', TRUE);
476  if (is_null($location)) continue;
477  if (!$GLOBALS['SQ_SYSTEM']->am->createAssetLink($location, $new_asset, SQ_LINK_NOTICE, $this->getPrefix().'_selected_create_location-'.$link_type['link_type'])) {
478  // bail out
479  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
480  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
481  $GLOBALS['SQ_SYSTEM']->restoreRunLevel();
482  return FALSE;
483  }
484  }
485 
486  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
487  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
488 
489  $GLOBALS['SQ_SYSTEM']->restoreRunLevel();
490  }
491 
492  // we are validating this user using email, so send them one
493  $replacements = Array();
494  $attrs = $GLOBALS['SQ_SYSTEM']->am->getAssetTypeAttributes($create_type);
495  foreach ($attrs as $attr => $type) {
496  if (($attr == 'password') || ($type['type'] == 'serialise')) {
497  continue;
498  }
499  $replacements[$attr] = $new_asset->attr($attr);
500  }
501 
502  $replacements['validation_url'] = current_url().'?action=validate&amid='.$this->_tmp['am_created_asset_key'];
503 
504  // add an email to the TO list for the user who just signed up
505  $email_attr = $this->getAttribute('validation_email_format');
506  $new_value = unserialize($email_attr->value);
507  $new_value['to'][] = $replacements['email'];
508  $email_attr->value = serialize($new_value);
509 
510  // let the email format attribute send the email for us
511  $email_attr->sendMail($replacements);
512  }//end if
513 
514  // the new user was created and can log in, so make sure the page is in the right state
515  if ($this->attr('create_status') >= SQ_STATUS_LIVE && !$this->attr('use_email_validation')) {
516  $this->_current_state = 'create_login';
517  $_POST['SQ_LOGIN_USERNAME'] = $this->_tmp['created_asset']->attr('username');
518  $this->_replacements['login_invite'] = $this->attr('login_invite');
519  $this->_replacements['login_form'] = $this->getKeywordReplacement('login_form');
520  } else {
521  $this->_current_state = 'create_no_login';
522  }
523  }//end if
524  break;
525  }//end switch
526  }//end if
527 
528  return TRUE;
529 
530  }//end _processGlobalActions()
531 
532 
546  function getCreateLocations($create_type)
547  {
548  $locs = parent::getCreateLocations($create_type);
549  if ($this->attr('use_email_validation') && !empty($locs)) {
550  // Validation is enabled, and we have some 'real' create locations,
551  // so go ahead and create the asset in the pending-users group,
552  // as long as the group exists
553  $locs = Array();
554  $pending_groupid = $this->_getPendingAccountsGroupId();
555  if ($pending_groupid) {
556  $locs = Array($pending_groupid => SQ_LINK_TYPE_1);
557  }
558  }
559  return $locs;
560 
561  }//end getCreateLocations()
562 
563 
572  function _modifyCreateLink(&$link)
573  {
574  parent::_modifyCreateLink($link);
575  if ($this->attr('use_email_validation')) {
576  $link['value'] = $this->_tmp['am_created_asset_key'];
577  }
578 
579  }//end _modifyCreateLink()
580 
581 
592  function _setCreateStatus(&$new_asset)
593  {
594  if ($this->attr('use_email_validation')) {
595  return TRUE;
596  } else {
597  return parent::_setCreateStatus($new_asset);
598  }
599 
600  }//end _setCreateStatus()
601 
602 
612  function processBackend(&$o, &$link)
613  {
614  if (SQ_IN_LIMBO) {
615  $current_user = $GLOBALS['SQ_SYSTEM']->user;
616 
617  if (!is_null($current_user) && !($current_user instanceof Public_User)) {
618  if ($current_user->processBackend($o, $link)) {
619  $this->_replacements['edit_details_success'] = $this->getKeywordReplacement('edit_details_success');
620  }
621  }
622 
623  return TRUE;
624  }
625 
626  return parent::processBackend($o, $link);
627 
628  }//end processBackend()
629 
630 
637  function backendAccess()
638  {
639  if (SQ_IN_LIMBO) {
640  return ($GLOBALS['SQ_SYSTEM']->user instanceof User);
641  } else {
642  return parent::backendAccess();
643  }
644 
645  }//end backendAccess()
646 
647 
654  function _getBodycopies()
655  {
656  $res = Array();
657 
658  $res['not_logged_in']['name'] = translate('not_logged_in');
659  $res['not_logged_in']['content'] = '<p>%create_error%%login_error%</p>'."\n".
660  '%create_invite%%create_form%%login_invite%%login_form%';
661 
662  $res['create_no_login']['name'] = translate('cms_account_manager_created_not_live');
663  $res['create_no_login']['content'] = translate('cms_account_manager_created_need_activation');
664 
665  $res['create_login']['name'] = translate('cms_account_manager_created_live');
666  $res['create_login']['content'] = translate('cms_account_manager_created_please_log_in')."\n%login_form%";
667 
668  $res['logged_in']['name'] = translate('logged_in');
669  $res['logged_in']['content'] = '<p>%edit_details_lock_error%%edit_details_success%</p>'."\n".
670  '%edit_details_invite%%edit_details_form%';
671 
672  return $res;
673 
674  }//end _getBodycopies()
675 
676 
677 //-- PENDING ACCOUNTS --//
678 
679 
689  {
690  $create_locations = Array();
691  $links = $GLOBALS['SQ_SYSTEM']->am->getLinks($userid, SQ_LINK_NOTICE, Array('user_group'), FALSE, 'minor');
692  foreach ($links as $link) {
693  // check that the link is actually a selectable create location link
694  // the link value should be in the format: 'PREFIX_selected_create_location-LINK_TYPE'
695  preg_match('/^'.$this->getPrefix().'_selected_create_location-([\d]*)$/', $link['value'], $matches);
696  if (!empty($matches)) {
697  $create_locations[$link['majorid']] = $matches[1];
698  }
699  }
700  return $create_locations;
701 
702  }//end getSelectedCreateLocationsForPendingUser()
703 
704 
713  function validateUser(&$user)
714  {
715  // Figure out create locations.
716  // - Mandatory ones are easily looked up
717  // - Rule-based ones are calculated from an
718  // array of asset attribute values
719  // - User-selected ones are grabbed from the
720  // user's notice links
721  list($create_type) = array_keys($this->attr('create_type'));
722 
723  $user_attributes = Array();
724  $attrs = $GLOBALS['SQ_SYSTEM']->am->getAssetTypeAttributes($create_type);
725  foreach ($attrs as $attr => $type) {
726  $user_attributes[$attr] = $user->attr($attr);
727  }
728 
729  $selected_create_locations = $this->getSelectedCreateLocationsForPendingUser($user->id);
730  $create_locations = parent::getFixedCreateLocations()
731  + parent::getRuleMatchCreateLocations($create_type, $user_attributes)
732  + $selected_create_locations;
733 
734  if (empty($create_locations)) {
735  trigger_localised_error('CMS0071', E_USER_WARNING);
736  return FALSE;
737  }
738 
739  // set the install run level because we are creating an asset without being
740  // logged in - so any write access checks will fail
741  $GLOBALS['SQ_SYSTEM']->setRunLevel(SQ_RUN_LEVEL_FORCED);
742 
743  $GLOBALS['SQ_SYSTEM']->changeDatabaseConnection('db2');
744  $GLOBALS['SQ_SYSTEM']->doTransaction('BEGIN');
745  // link the user asset into the locations it is supposed to go
746  foreach ($create_locations as $link_parentid => $link_type) {
747  $link_parent = $GLOBALS['SQ_SYSTEM']->am->getAsset($link_parentid, '', TRUE);
748  if (is_null($link_parent)) continue;
749  if (!$GLOBALS['SQ_SYSTEM']->am->createAssetLink($link_parent, $user, $link_type)) {
750  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
751  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
752  $GLOBALS['SQ_SYSTEM']->restoreRunLevel();
753  return FALSE;
754  }
755 
756  // Bug #5509: Account Manager User asset webpath conflict.
757  $current_paths = $user->getWebPaths();
758  require_once SQ_INCLUDE_PATH.'/general_occasional.inc';
759  $valid_paths = make_valid_web_paths($current_paths, $user->id);
760  $valid_paths = $GLOBALS['SQ_SYSTEM']->am->webPathsInUse($link_parent, $valid_paths, $user->id, TRUE);
761  if (!$user->saveWebPaths($valid_paths, FALSE)){
762  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
763  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
764  $GLOBALS['SQ_SYSTEM']->restoreRunLevel();
765  return FALSE;
766  }
767  }
768 
769  // remove the selectable create location notice links, if they exist
770  foreach ($selected_create_locations as $link_parentid => $link_type) {
771  $link = $GLOBALS['SQ_SYSTEM']->am->getLinkByAsset($link_parentid, $user->id, SQ_LINK_NOTICE, $this->getPrefix().'_selected_create_location-'.$link_type);
772  if (!empty($link)) {
773  if (!$GLOBALS['SQ_SYSTEM']->am->deleteAssetLink($link['linkid'])) {
774  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
775  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
776  $GLOBALS['SQ_SYSTEM']->restoreRunLevel();
777  return FALSE;
778  }
779  }
780  }
781 
782  // remove the link from the pending accounts group
783  if (!$this->_removePendingUserFromPendingGroup($user->id)) {
784  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
785  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
786  $GLOBALS['SQ_SYSTEM']->restoreRunLevel();
787  return FALSE;
788  }
789 
790  // set the status of the asset
791  if (!parent::_setCreateStatus($user)) {
792  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
793  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
794  $GLOBALS['SQ_SYSTEM']->restoreRunLevel();
795  return FALSE;
796  }
797 
798  // if we move an asset, we need to update the urls (lookups) as well.
799  $hh =& $GLOBALS['SQ_SYSTEM']->getHipoHerder();
800  $vars = Array('assetids' => Array($user->id), 'auto_add_remaps' => FALSE);
801  $hipo_empty_array = $hh->freestyleHipo('hipo_job_update_lookups', $vars);
802 
803  // Here after moving the asset away from pending accounts folder we check for the
804  // permission/metadata/workflow of the new parent asset and cascade same permission
805  // to the new user also if the hipo was not successfull - fullstop and rollback.
806  foreach ($create_locations as $location_id => $link_type) {
807  foreach (Array(SQ_PERMISSION_READ, SQ_PERMISSION_WRITE, SQ_PERMISSION_ADMIN) as $perm) {
808  $set_perms = $GLOBALS['SQ_SYSTEM']->am->getAssetPermissionByCascade($location_id, $perm, NULL, TRUE);
809  foreach ($set_perms as $perm_info) {
810  if (!empty($hipo_empty_array) || !$GLOBALS['SQ_SYSTEM']->am->setPermission($user->id, $perm_info['userid'], $perm, $perm_info['granted'], TRUE, TRUE)) {
811  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
812  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
813  $GLOBALS['SQ_SYSTEM']->restoreRunLevel();
814  return FALSE;
815  }
816  }
817  }//end foreach
818 
819  $mm = $GLOBALS['SQ_SYSTEM']->getMetadataManager();
820  $mm_schema = $mm->getSchemas($location_id, NULL, TRUE);
821  foreach ($mm_schema as $schema_id => $granted ) {
822  if (!$mm->setSchema($user->id, $schema_id, $granted)) {
823  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
824  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
825  $GLOBALS['SQ_SYSTEM']->restoreRunLevel();
826  return FALSE;
827  }//end if
828  }//end foreach
829 
830  $wfm = $GLOBALS['SQ_SYSTEM']->getWorkflowManager();
831  $wf_schema = $wfm->getSchemas($location_id, NULL, FALSE, TRUE);
832  foreach ($wf_schema as $schema_id => $granted ) {
833  if (!$wfm->setSchema($user->id, $schema_id, $granted)) {
834  $GLOBALS['SQ_SYSTEM']->doTransaction('ROLLBACK');
835  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
836  $GLOBALS['SQ_SYSTEM']->restoreRunLevel();
837  return FALSE;
838  }//end if
839  }//end foreach
840  }
841 
842  // all done
843  $GLOBALS['SQ_SYSTEM']->doTransaction('COMMIT');
844  $GLOBALS['SQ_SYSTEM']->restoreDatabaseConnection();
845  $GLOBALS['SQ_SYSTEM']->restoreRunLevel();
846  return TRUE;
847 
848  }//end validateUser()
849 
850 
861  function hipoValidateUser($index, $item, $settings)
862  {
863  // load the user asset
864  $user = $GLOBALS['SQ_SYSTEM']->am->getAsset($item);
865  if (is_null($user)) return FALSE;
866  $validated = $this->validateUser($user);
867  $GLOBALS['SQ_SYSTEM']->am->forgetAsset($user);
868  return $validated;
869 
870  }//end hipoValidateUser()
871 
872 
883  function hipoDeleteUser($index, $item, $settings)
884  {
885  $user = $GLOBALS['SQ_SYSTEM']->am->getAsset($item);
886  $user->saveWebPaths(Array());
887  $GLOBALS['SQ_SYSTEM']->am->trashAsset($item);
888 
889  // trick the user asset into thinking we're purging the
890  // assets (which we are, just not from the trash), so it
891  // will release its hold on its inbox and workspace
892  $GLOBALS['SQ_PURGING_TRASH'] = TRUE;
893 
894  // Delete the inbox and remove its URLs
895  $inbox_link = $user->getInboxLink();
896  $inbox = $GLOBALS['SQ_SYSTEM']->am->getAsset($inbox_link['minorid']);
897  $GLOBALS['SQ_SYSTEM']->am->trashAsset($inbox->id);
898  $inbox->updateLookups();
899 
900  // Delete the workspace and remove its URLs
901  $workspace = $user->getWorkspace();
902  $workspace->saveWebPaths(Array());
903  $GLOBALS['SQ_SYSTEM']->am->trashAsset($workspace->id);
904  $workspace->updateLookups();
905 
906  $inbox->delete(FALSE);
907  $workspace->delete(FALSE);
908 
909  $GLOBALS['SQ_PURGING_TRASH'] = FALSE;
910 
911  // Delete the account
912  $user->delete(FALSE);
913  unset($user);
914 
915  return TRUE;
916 
917  }//end hipoDeleteUser()
918 
919 
928  function resendValidation($username=NULL)
929  {
930  if (is_null($username)) {
931  if (!empty($_REQUEST[$this->getPrefix().'_resend_validation_username'])) {
932  $username = $_REQUEST[$this->getPrefix().'_resend_validation_username'];
933  }
934  }
935 
936  if (!is_null($username) && $this->attr('use_email_validation')) {
937  // add an email to the TO list for the user who just signed up
938 
939  $auth_folder = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('authentication_folder');
940  $auth_systems = $auth_folder->getAuthSystems();
941  $user = NULL;
942  foreach ($auth_systems as $systemid) {
943  $system = $GLOBALS['SQ_SYSTEM']->am->getAsset($systemid);
944  if (is_null($system)) continue;
945  $user = $system->locateUser($username);
946  if (!is_null($user) && $user->id) {
947  break;
948  }
949  }
950 
951  if (is_null($user)) {
952  $this->_errors[] = translate('cms_account_manager_keyword_resend_validation_user_not_found');
953  return FALSE;
954 
955  } else {
956  if ($validation_key = $this->getValidationKeyForUser($user)) {
957  $replacements = Array();
958  list($create_type) = array_keys($this->attr('create_type'));
959  $attrs = $GLOBALS['SQ_SYSTEM']->am->getAssetTypeAttributes($create_type);
960  foreach ($attrs as $attr => $type) {
961  if (($attr == 'password') || ($type['type'] == 'serialise')) {
962  continue;
963  }
964  $replacements[$attr] = $user->attr($attr);
965  }
966  $url = SQ_IN_CRON ? $this->getURL() : current_url();
967  $replacements['validation_url'] = $url.'?action=validate&amid='.$validation_key;
968 
969  // add an email to the TO list for the user who just signed up
970  $email_attr = $this->getAttribute('validation_email_format');
971  $new_value = unserialize($email_attr->value);
972  $new_value['to'][] = $replacements['email'];
973  $new_email_attr = new Asset_Attribute_Email_Format(0, serialize($new_value));
974  if (is_null($new_email_attr)) {
975  $this->_errors[] = translate('cms_account_manager_keyword_resend_validation_cannot_send_user');
976  return FALSE;
977  }
978 
979  // let the email format attribute send the email for us
980  $new_email_attr->sendMail($replacements);
981  $this->_replacements['resend_validation_success'] = $this->getKeywordReplacement('re_send_validation_success');
982  return TRUE;
983 
984  } else {
985  $this->_errors[] = translate('cms_account_manager_keyword_resend_validation_cannot_send_user');
986  return FALSE;
987  }
988 
989  }//end else
990 
991  } else {
992  $this->_errors[] = translate('cms_account_manager_keyword_resend_validation_cannot_send_user');
993  return FALSE;
994  }
995 
996  return FALSE;
997 
998  }//end resendValidation()
999 
1000 
1009  function getValidationKeyForUser(&$user)
1010  {
1011  $pending_usergroup_id = $this->_getPendingAccountsGroupId();
1012  $links = $GLOBALS['SQ_SYSTEM']->am->getLinkByAsset($pending_usergroup_id, $user->id);
1013 
1014  // we should only have one link
1015  if (!empty($links)) return $links['value'];
1016  return FALSE;
1017 
1018  }//end getValidationKeyForUser()
1019 
1020 
1028  {
1029  $group_link = Array('asset' => &$this, 'link_type' => SQ_LINK_TYPE_2, 'sort_order' => 0, 'is_dependant' => 1, 'is_exclusive' => 1, 'value' => 'pending_accounts');
1030  $GLOBALS['SQ_SYSTEM']->am->includeAsset('user_group');
1031 
1032  $group = new User_Group();
1033  $group->setAttrValue('name', 'Pending Accounts');
1034  if (!$group->create($group_link)) {
1035  return FALSE;
1036  }
1037 
1038  return TRUE;
1039 
1040  }//end _createPendingAccountsGroup()
1041 
1042 
1050  {
1051  $link = $GLOBALS['SQ_SYSTEM']->am->getLink($this->id, SQ_LINK_TYPE_2, 'user_group', TRUE, 'pending_accounts');
1052  if (empty($link)) {
1053  return 0;
1054  } else {
1055  return $link['minorid'];
1056  }
1057 
1058  }//end _getPendingAccountsGroupId()
1059 
1060 
1068  {
1069  $user = NULL;
1070  $id = (isset($_REQUEST['amid'])) ? trim($_REQUEST['amid']) : '';
1071  if (!empty($id)) {
1072  $pending_link = $GLOBALS['SQ_SYSTEM']->am->getLink($this->id, SQ_LINK_TYPE_2, 'user_group', TRUE, 'pending_accounts');
1073  if (!empty($pending_link)) {
1074  $link = $GLOBALS['SQ_SYSTEM']->am->getLink($pending_link['minorid'], SQ_LINK_TYPE_1, 'user', FALSE, $id);
1075  if (!empty($link)) {
1076  $user = $GLOBALS['SQ_SYSTEM']->am->getAsset($link['minorid'], $link['minor_type_code']);
1077  }
1078  }
1079  }
1080  return $user;
1081 
1082  }//end _getCurrentPendingUser()
1083 
1084 
1094  {
1095  $pending_accounts_groupid = $this->_getPendingAccountsGroupId();
1096  if (!empty($pending_accounts_groupid)) {
1097  $link = $GLOBALS['SQ_SYSTEM']->am->getLinkByAsset($pending_accounts_groupid, $userid, SQ_LINK_TYPE_1);
1098  if (!empty($link)) {
1099  $resent_link = $GLOBALS['SQ_SYSTEM']->am->getLinkByAsset($pending_accounts_groupid, $userid, SQ_LINK_NOTICE, 'validation_email_resent');
1100  if (!empty($resent_link)) $GLOBALS['SQ_SYSTEM']->am->deleteAssetLink($resent_link['linkid']);
1101  return $GLOBALS['SQ_SYSTEM']->am->deleteAssetLink($link['linkid']);
1102  }
1103  }
1104  return FALSE;
1105 
1106  }//end _removePendingUserFromPendingGroup()
1107 
1108 
1116  {
1117  $users = Array();
1118 
1119  $group_folder_id = $this->_getPendingAccountsGroupId();
1120  if (!empty($group_folder_id)) {
1121  $links = $GLOBALS['SQ_SYSTEM']->am->getLinks($group_folder_id, SQ_LINK_TYPE_1, 'user', FALSE);
1122  foreach ($links as $link) {
1123  $users[] = $link['minorid'];
1124  }
1125  }
1126 
1127  return $users;
1128 
1129  }//end _getPendingUserIds()
1130 
1131 
1132 //-- KEYWORD DESCRIPTION --//
1133 
1134 
1145  function onRequestKeywords(&$broadcaster, $vars=Array())
1146  {
1147  if (!isset($vars['keywords'])) return;
1148 
1149  // get type-code
1150  $parents = $GLOBALS['SQ_SYSTEM']->am->getParents($broadcaster->id, 'bodycopy', TRUE);
1151  $type_links = $GLOBALS['SQ_SYSTEM']->am->getLinks($this->id, SQ_LINK_TYPE_2, 'bodycopy');
1152  $bodycopy_type = '';
1153  foreach ($type_links as $link_info) {
1154  if (isset($parents[$link_info['minorid']])) {
1155  $bodycopy_type = $link_info['value'];
1156  }
1157  }
1158 
1159  switch ($bodycopy_type) {
1160  case 'not_logged_in' :
1161  $vars['keywords'] = array_merge($vars['keywords'], $this->_getNotLoggedInKeywords());
1162  break;
1163  case 'logged_in' :
1164  $vars['keywords'] = array_merge($vars['keywords'], $this->_getLoggedInKeywords());
1165  break;
1166  case 'create_login' :
1167  case 'create_no_login' :
1168  $vars['keywords'] = array_merge($vars['keywords'], $this->_getCreateLoginKeywords());
1169  break;
1170 
1171  }
1172 
1173  $vars['keywords'] = array_merge($vars['keywords'], $this->_getSelectableLocationKeywords());
1174  $vars['keywords'] = array_merge($vars['keywords'], $this->_getDynamicLocationKeywords());
1175  }//end onRequestKeywords()
1176 
1177 
1185  {
1186  $keywords = parent::_getLoggedInKeywords();
1187 
1188  // add new keywords
1189  $keywords['edit_details_invite'] = translate('cms_account_manager_keyword_edit_details_invite');
1190  $keywords['edit_details_form'] = translate('cms_account_manager_keyword_edit_details_form');
1191  $keywords['edit_details_success'] = translate('cms_account_manager_keyword_edit_details_success');
1192  $keywords['edit_details_lock_error'] = translate('cms_account_manager_keyword_edit_details_lock_error');
1193 
1194  $keywords['logout_form'] = translate('cms_asset_builder_keyword_logout_form');
1195 
1196  // Exclude CAPTCHA keywords from the "Logged In" form. Presume if the user has logged in, that they are not an artificial intelligence
1197  if ($this->attr('require_captcha')) {
1198  unset($keywords['form_captcha']);
1199  unset($keywords['form_captcha_image']);
1200  unset($keywords['form_captcha_field']);
1201  unset($keywords['form_captcha_link']);
1202  }
1203 
1204  return $keywords;
1205 
1206  }//end _getLoggedInKeywords()
1207 
1208 
1216  {
1217  $keywords = parent::_getCreatedKeywords();
1218 
1219  // override parent's keywords
1220  $keywords['create_invite'] = translate('cms_account_manager_keyword_create_invite');
1221  $keywords['create_form'] = translate('cms_account_manager_keyword_create_form');
1222  $keywords['create_error'] = translate('cms_account_manager_keyword_create_error');
1223  $keywords['resend_validation_form'] = translate('cms_account_manager_keyword_resend_validation_form');
1224 
1225  return $keywords;
1226 
1227  }//end _getCreateLoginKeywords()
1228 
1229 
1237  {
1238  $keywords = parent::_getNotLoggedInKeywords();
1239  $keywords['resend_validation_error'] = translate('cms_account_manager_keyword_resend_validation_error');
1240  $keywords['resend_validation_form'] = translate('cms_account_manager_keyword_resend_validation_form');
1241  $keywords['resend_validation_success'] = translate('cms_account_manager_keyword_resend_validation_success');
1242 
1243  if ($this->attr('require_captcha')) {
1244  $keywords['form_captcha'] = translate('cms_asset_builder_keyword_form_captcha');
1245  $keywords['form_captcha_image'] = translate('cms_asset_builder_keyword_form_captcha_image');
1246  $keywords['form_captcha_field'] = translate('cms_asset_builder_keyword_form_captcha_field');
1247  $keywords['form_captcha_link'] = translate('cms_asset_builder_keyword_form_captcha_link');
1248  }
1249 
1250  return $keywords;
1251 
1252  }//end _getNotLoggedInKeywords()
1253 
1254 
1255  //-- KEYWORD REPLACEMENT --//
1256 
1257 
1265  {
1266  ob_start();
1267  text_box($this->getPrefix().'_resend_validation_username', '',20);
1268  submit_button('', $this->attr('resend_validation_button'), 'document.getElementById(\'AB_'.$this->id.'_ASSET_BUILDER_ACTION\').value = \'resend_validation\';');
1269  return ob_get_clean();
1270 
1271  }//end getReSendValidationFormKeywordReplacement()
1272 
1273 
1281  {
1282  return $this->attr('edit_details_lock_error');
1283 
1284  }//end getEditDetailsLockErrorKeywordReplacement()
1285 
1286 
1294  {
1295  return $this->attr('edit_details_success');
1296 
1297  }//end getEditDetailsSuccessKeywordReplacement()
1298 
1299 
1307  {
1308  return $this->attr('resend_validation_success');
1309 
1310  }//end getReSendValidationSuccessKeywordReplacement()
1311 
1312 
1320  {
1321  ob_start();
1322  ?>
1323  <input type="hidden" name="SQ_LOGIN_ACCOUNT_MANAGER_STATE" value="<?php echo $this->_current_state; ?>" />
1324  <?php
1325  $output = ob_get_clean();
1326 
1327  return $output.parent::getLoginFormKeywordReplacement();
1328 
1329  }//end getLoginFormKeywordReplacement()
1330 
1331 
1339  {
1340  ob_start();
1341  ?>
1342  <form id="<?php echo $this->getPrefix() ?>_logout" method="POST" action="<?php echo current_url(TRUE, TRUE); ?>?SQ_ACTION=logout">
1343  <?php echo submit_button('logout', translate('logout')); ?>
1344  </form>
1345  <?php
1346  $replacement = ob_get_contents();
1347 
1348  ob_end_clean();
1349  return $replacement;
1350 
1351  }//end getLogoutFormKeywordReplacement()
1352 
1353 
1354 }//end class
1355 
1356 ?>