PageRenderTime 56ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/src/Handler/Person.php

http://leaguerunner.googlecode.com/
PHP | 2181 lines | 1814 code | 270 blank | 97 comment | 233 complexity | 5e98f1e4d794591d163331c6ceed7454 MD5 | raw file
Possible License(s): AGPL-1.0

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

  1. <?php
  2. /*
  3. * Code for dealing with user accounts
  4. */
  5. function person_dispatch()
  6. {
  7. $op = arg(1);
  8. $id = arg(2);
  9. switch($op) {
  10. case 'create':
  11. $obj = new PersonCreate;
  12. break;
  13. case 'edit':
  14. $obj = new PersonEdit;
  15. $obj->person = person_load( array('user_id' => $id) );
  16. break;
  17. case 'view':
  18. $obj = new PersonView;
  19. $obj->person = person_load( array('user_id' => $id) );
  20. break;
  21. case 'delete':
  22. $obj = new PersonDelete;
  23. $obj->person = person_load( array('user_id' => $id) );
  24. break;
  25. case 'search':
  26. $obj = new PersonSearch;
  27. break;
  28. case 'approve':
  29. $obj = new PersonApproveNewAccount;
  30. $obj->person = person_load( array('user_id' => $id) );
  31. break;
  32. case 'activate':
  33. $obj = new PersonActivate;
  34. $obj->person = person_load( array('user_id' => $id) );
  35. break;
  36. case 'signwaiver':
  37. $obj = new PersonSignWaiver;
  38. break;
  39. case 'signdogwaiver':
  40. $obj = new PersonSignDogWaiver;
  41. break;
  42. case 'listnew':
  43. $obj = new PersonListNewAccounts;
  44. break;
  45. case 'changepassword':
  46. $obj = new PersonChangePassword;
  47. $obj->person = person_load( array('user_id' => $id) );
  48. break;
  49. case 'forgotpassword':
  50. $obj = new PersonForgotPassword;
  51. break;
  52. case 'historical':
  53. $obj = new PersonHistorical;
  54. $obj->person = person_load( array('user_id' => $id) );
  55. break;
  56. default:
  57. $obj = null;
  58. }
  59. if( $obj->person ) {
  60. person_add_to_menu( $obj->person );
  61. }
  62. return $obj;
  63. }
  64. /**
  65. * The permissions check for all Person actions.
  66. */
  67. function person_permissions ( &$user, $action, $arg1 = NULL, $arg2 = NULL )
  68. {
  69. $self_edit_fields = array(); # TODO
  70. $create_fields = array( 'name', 'username', 'password');
  71. $create_fields = array_merge($self_edit_fields, $create_fields);
  72. $all_view_fields = array( 'name', 'gender', 'skill', 'willing_to_volunteer' );
  73. if (variable_get('dog_questions', 1)) {
  74. $all_view_fields[] = 'dog';
  75. }
  76. $restricted_contact_fields = array( 'email', 'home_phone', 'work_phone', 'mobile_phone' );
  77. $captain_view_fields = array( 'height', 'shirtsize' );
  78. $self_view_fields = array('username','birthdate','address','last_login', 'member_id','height','shirtsize');
  79. $self_view_fields = array_merge($all_view_fields, $restricted_contact_fields, $self_view_fields);
  80. switch( $action ) {
  81. case 'create':
  82. return true;
  83. break;
  84. case 'edit':
  85. if( 'new' == $arg1) {
  86. // Almost all fields can be edited for new players
  87. if( $arg2 ) {
  88. return( in_array( $arg2, $create_fields ) );
  89. } else {
  90. return true;
  91. }
  92. }
  93. if( ! $user->is_active() ) {
  94. return false;
  95. }
  96. if( $user->user_id == $arg1 ) {
  97. if( $arg2 ) {
  98. return( in_array( $arg2, $self_edit_fields ) );
  99. } else {
  100. return true;
  101. }
  102. }
  103. break;
  104. case 'password_change':
  105. // User can change own password
  106. if( is_numeric( $arg1 )) {
  107. if( $user->user_id == $arg1 ) {
  108. return true;
  109. }
  110. }
  111. break;
  112. case 'view':
  113. if( ! ($user && $user->is_active()) ) {
  114. return false;
  115. }
  116. if( is_numeric( $arg1 )) {
  117. if( $user->user_id == $arg1 ) {
  118. // Viewing yourself allowed, most fields
  119. if( $arg2 ) {
  120. return( in_array( $arg2, $self_view_fields ) );
  121. } else {
  122. return true;
  123. }
  124. } else {
  125. // Other user. Now comes the hard part
  126. $player = person_load( array('user_id' => $arg1) );
  127. // New or locked players cannot be viewed.
  128. if( $player->status == 'new' || $player->status == 'locked' ) {
  129. return false;
  130. }
  131. $sess_user_teams = implode(",",array_keys($user->teams));
  132. $viewable_fields = $all_view_fields;
  133. /* If player is a captain, their email is viewable */
  134. if( $player->is_a_captain ) {
  135. // Plus, can view email
  136. $viewable_fields[] = 'email';
  137. }
  138. if($user->is_a_captain) {
  139. /* If the current user is a team captain, and the requested user is on
  140. * their team, they are allowed to view email/phone
  141. */
  142. foreach( $player->teams as $team ) {
  143. if( $user->is_captain_of( $team->team_id ) &&
  144. $team->position != 'captain_request' ) {
  145. /* They are, so publish email and phone */
  146. $viewable_fields = array_merge($all_view_fields, $restricted_contact_fields, $captain_view_fields);
  147. break;
  148. }
  149. }
  150. /* If the current user is a team captain, and the requested user is
  151. * captain for a "nearby" team, they are allowed to view email/phone
  152. */
  153. if($player->is_a_captain) {
  154. foreach( $player->teams as $player_team ) {
  155. if( $player->is_captain_of( $player_team->team_id ) ) {
  156. foreach( $user->teams as $user_team ) {
  157. if( $user->is_captain_of( $user_team->team_id ) &&
  158. $player_team->league_id == $user_team->league_id )
  159. {
  160. $viewable_fields = array_merge($all_view_fields, $restricted_contact_fields);
  161. }
  162. }
  163. }
  164. }
  165. }
  166. }
  167. /* Coordinator info is viewable */
  168. if($player->is_a_coordinator) {
  169. $viewable_fields = array_merge($all_view_fields, $restricted_contact_fields);
  170. }
  171. /* Coordinators get to see phone numbers of the captains they handle */
  172. if($user->is_a_coordinator && $player->is_a_captain) {
  173. foreach( $player->teams as $team ) {
  174. if( $player->is_captain_of( $team->team_id ) &&
  175. $user->coordinates_league_containing( $team->team_id ) )
  176. {
  177. $viewable_fields = array_merge($all_view_fields, $restricted_contact_fields);
  178. }
  179. }
  180. }
  181. // Finally, perform the check and return
  182. if( $arg2 ) {
  183. return( in_array( $arg2, $viewable_fields ) );
  184. } else {
  185. return true;
  186. }
  187. }
  188. }
  189. break;
  190. case 'list':
  191. case 'search':
  192. if( ! ($user && $user->is_active()) ) {
  193. return false;
  194. }
  195. return($user->class != 'visitor');
  196. case 'approve':
  197. // administrator-only
  198. case 'delete':
  199. // administrator-only
  200. case 'listnew':
  201. // administrator-only
  202. default:
  203. return false;
  204. }
  205. return false;
  206. }
  207. /**
  208. * Generate the menu items for the "Players" and "My Account" sections.
  209. */
  210. function person_menu()
  211. {
  212. global $lr_session;
  213. $id = $lr_session->attr_get('user_id');
  214. menu_add_child('_root', 'myaccount','My Account', array('weight' => -10, 'link' => "person/view/$id"));
  215. menu_add_child('myaccount', 'myaccount/edit','edit account', array('weight' => -10, 'link' => "person/edit/$id"));
  216. menu_add_child('myaccount', 'myaccount/pass', 'change password', array( 'link' => "person/changepassword/$id"));
  217. menu_add_child('myaccount', 'myaccount/signwaiver', 'view/sign player waiver', array( 'link' => "person/signwaiver", 'weight' => 3));
  218. if (variable_get('dog_questions', 1) && $lr_session->attr_get('has_dog') == 'Y') {
  219. menu_add_child('myaccount', 'myaccount/signdogwaiver', 'view/sign dog waiver', array( 'link' => "person/signdogwaiver", 'weight' => 4));
  220. }
  221. # Don't show "Players" menu for non-players.
  222. if( ! $lr_session->is_player() ) {
  223. return;
  224. }
  225. menu_add_child('_root','person',"Players", array('weight' => -9));
  226. if($lr_session->has_permission('person','list') ) {
  227. menu_add_child('person','person/search',"search players", array('link' => 'person/search'));
  228. }
  229. if($lr_session->is_admin()) {
  230. $newUsers = person_count(array( 'status' => 'new' ));
  231. if($newUsers) {
  232. menu_add_child('person','person/listnew',"approve new accounts ($newUsers pending)", array('link' => "person/listnew"));
  233. }
  234. menu_add_child('person', 'person/create', "create account", array('link' => "person/create", 'weight' => 1));
  235. # Admin menu
  236. menu_add_child('settings', 'settings/person', 'user settings', array('link' => 'settings/person'));
  237. menu_add_child('statistics', 'statistics/person', 'player statistics', array('link' => 'statistics/person'));
  238. }
  239. }
  240. /**
  241. * Periodic tasks to perform. This should handle any internal checkpointing
  242. * necessary, as the cron task may be called more or less frequently than we
  243. * expect.
  244. */
  245. function person_cron()
  246. {
  247. global $dbh;
  248. $output = '';
  249. if( variable_get('registration', 0) ) {
  250. $output .= h2('Membership welcome letters');
  251. // Defaulting the value here to 0 matches no real events while preventing SQL errors.
  252. $registration_ids = variable_get('membership_ids', '0');
  253. // TODO: Make the rollover date configurable; this starts the new year's letters in April
  254. $year = date('Y');
  255. if (date('n') < 4)
  256. -- $year;
  257. $sth = $dbh->prepare("SELECT user_id FROM person
  258. WHERE user_id IN
  259. (SELECT DISTINCT user_id FROM registrations
  260. WHERE registration_id IN ($registration_ids)
  261. AND payment = 'Paid')
  262. AND user_id NOT IN
  263. (SELECT secondary_id FROM activity_log
  264. WHERE type = ? AND primary_id = ?)");
  265. $sth->execute( array("email_membership_letter", $year) );
  266. $emailed = 0;
  267. while( $id = $sth->fetchColumn() ) {
  268. $person = person_load( array('user_id' => $id) );
  269. if ($person->send_membership_letter())
  270. ++ $emailed;
  271. }
  272. $output .= para("Emailed $emailed membership letters.");
  273. }
  274. return "$output<pre>Completed person_cron run</pre>";
  275. }
  276. /**
  277. * Player viewing handler
  278. */
  279. class PersonView extends Handler
  280. {
  281. var $person;
  282. function has_permission ()
  283. {
  284. global $lr_session;
  285. if(!$this->person) {
  286. error_exit("That user does not exist");
  287. }
  288. return $lr_session->has_permission('person','view', $this->person->user_id);
  289. }
  290. function process ()
  291. {
  292. $this->title = 'View';
  293. $this->setLocation(array(
  294. $this->person->fullname => 'person/view/' . $this->person->user_id,
  295. $this->title => 0));
  296. return $this->generateView($this->person);
  297. }
  298. function generateView (&$person)
  299. {
  300. global $lr_session;
  301. $rows[] = array("Name:", $person->fullname);
  302. if( ! ($lr_session->is_player() || ($lr_session->attr_get('user_id') == $person->user_id)) ) {
  303. return "<div class='pairtable'>" . table(null, $rows) . "</div>";
  304. }
  305. if($lr_session->has_permission('person','view',$person->user_id, 'username') ) {
  306. $rows[] = array("System Username:", $person->username);
  307. }
  308. if($lr_session->has_permission('person','view',$person->user_id, 'member_id') ) {
  309. if($person->member_id) {
  310. $rows[] = array(variable_get('app_org_short_name', 'League') . ' Member ID:', $person->member_id);
  311. } else {
  312. $rows[] = array(variable_get('app_org_short_name', 'League') . ' Member ID:', 'Not a member of ' . variable_get('app_org_short_name', 'the league'));
  313. }
  314. }
  315. if($person->allow_publish_email == 'Y') {
  316. $rows[] = array("Email Address:", l($person->email, "mailto:$person->email") . " (published)");
  317. } else {
  318. if($lr_session->has_permission('person','view',$person->user_id, 'email') ) {
  319. $rows[] = array("Email Address:", l($person->email, "mailto:$person->email") . " (private)");
  320. }
  321. }
  322. foreach(array('home','work','mobile') as $type) {
  323. $item = "${type}_phone";
  324. $publish = "publish_$item";
  325. if($person->$publish == 'Y') {
  326. $rows[] = array("Phone ($type):", $person->$item . " (published)");
  327. } else {
  328. if($lr_session->has_permission('person','view',$person->user_id, $item) && isset($person->$item) ) {
  329. $rows[] = array("Phone ($type):", $person->$item . " (private)");
  330. }
  331. }
  332. }
  333. if($lr_session->has_permission('person','view',$person->user_id, 'address')) {
  334. $rows[] = array("Address:",
  335. format_street_address(
  336. $person->addr_street,
  337. $person->addr_city,
  338. $person->addr_prov,
  339. $person->addr_country,
  340. $person->addr_postalcode
  341. )
  342. );
  343. }
  344. if($lr_session->has_permission('person','view',$person->user_id, 'birthdate')) {
  345. $rows[] = array('Birthdate:', $person->birthdate);
  346. }
  347. if($lr_session->has_permission('person','view',$person->user_id, 'height')) {
  348. $rows[] = array('Height:', $person->height ? "$person->height inches" : "Please edit your account to enter your height");
  349. }
  350. if($lr_session->has_permission('person','view',$person->user_id, 'gender')) {
  351. $rows[] = array("Gender:", $person->gender);
  352. }
  353. if($lr_session->has_permission('person','view',$person->user_id, 'shirtsize')) {
  354. $rows[] = array('Shirt Size:', $person->shirtsize);
  355. }
  356. if($lr_session->has_permission('person','view',$person->user_id, 'skill')) {
  357. $skillAry = getOptionsForSkill();
  358. $rows[] = array("Skill Level:", $skillAry[$person->skill_level]);
  359. $rows[] = array("Year Started:", $person->year_started);
  360. }
  361. if($lr_session->has_permission('person','view',$person->user_id, 'class')) {
  362. $rows[] = array("Account Class:", $person->class);
  363. }
  364. if($lr_session->has_permission('person','view',$person->user_id, 'status')) {
  365. $rows[] = array("Account Status:", $person->status);
  366. }
  367. if(variable_get('dog_questions', 1)) {
  368. if($lr_session->has_permission('person','view',$person->user_id, 'dog')) {
  369. $rows[] = array("Has Dog:",($person->has_dog == 'Y') ? "yes" : "no");
  370. if($person->has_dog == 'Y') {
  371. $rows[] = array("Dog Waiver Signed:",($person->dog_waiver_signed) ? $person->dog_waiver_signed : "Not signed");
  372. }
  373. }
  374. }
  375. if($lr_session->has_permission('person','view',$person->user_id, 'willing_to_volunteer')) {
  376. $rows[] = array('Can ' . variable_get('app_org_short_name', 'the league') . ' contact you with a survey about volunteering?',($person->willing_to_volunteer == 'Y') ? 'yes' : 'no');
  377. }
  378. if($lr_session->has_permission('person','view',$person->user_id, 'contact_for_feedback')) {
  379. $rows[] = array('From time to time, ' . variable_get('app_org_short_name', 'the league') .
  380. ' would like to contact members with information on our programs and to solicit feedback. ' .
  381. 'Can ' . variable_get('app_org_short_name', 'the league') . ' contact you in this regard? ',
  382. ($person->contact_for_feedback == 'Y') ? 'yes' : 'no');
  383. }
  384. if($lr_session->has_permission('person','view',$person->user_id, 'last_login')) {
  385. if($person->last_login) {
  386. $rows[] = array('Last Login:',
  387. $person->last_login . ' from ' . $person->client_ip);
  388. } else {
  389. $rows[] = array('Last Login:', 'Never logged in');
  390. }
  391. }
  392. $rosterPositions = getRosterPositions();
  393. $teams = array();
  394. while(list(,$team) = each($person->teams)) {
  395. $teams[] = array(
  396. $rosterPositions[$team->position],
  397. 'on',
  398. l($team->name, "team/view/$team->id"),
  399. "(" . l($team->league_name, "league/view/$team->league_id") . ")"
  400. );
  401. }
  402. reset($person->teams);
  403. $rows[] = array("Teams:", table( null, $teams) );
  404. if( count ($person->historical_teams) ) {
  405. $rows[] = array( '', 'There is also ' . l('historical team data', "person/historical/$person->user_id") . ' saved');
  406. }
  407. if( $person->is_a_coordinator ) {
  408. $leagues = array();
  409. foreach( $person->leagues as $league ) {
  410. $leagues[] = array(
  411. "Coordinator of",
  412. l($league->fullname, "league/view/$league->league_id")
  413. );
  414. }
  415. reset($person->leagues);
  416. $rows[] = array("Leagues:", table( null, $leagues) );
  417. }
  418. if( variable_get('registration', 0) ) {
  419. if($lr_session->has_permission('registration','history',$person->user_id)) {
  420. $rows[] = array("Registration:", l('View registration history', "registration/history/$person->user_id"));
  421. }
  422. }
  423. return "<div class='pairtable'>" . table(null, $rows) . "</div>";
  424. }
  425. }
  426. /**
  427. * Delete an account
  428. */
  429. class PersonDelete extends PersonView
  430. {
  431. var $person;
  432. function has_permission()
  433. {
  434. global $lr_session;
  435. if(!$this->person) {
  436. error_exit("That user does not exist");
  437. }
  438. return $lr_session->has_permission('person','delete', $this->person->user_id);
  439. }
  440. function process ()
  441. {
  442. global $lr_session;
  443. $this->title = 'Delete';
  444. $edit = $_POST['edit'];
  445. /* Safety check: Don't allow us to delete ourselves */
  446. if($lr_session->attr_get('user_id') == $this->person->user_id) {
  447. error_exit("You cannot delete your own account!");
  448. }
  449. if($edit['step'] == 'perform') {
  450. $this->person->delete();
  451. local_redirect(url("person/search"));
  452. return $rc;
  453. }
  454. $this->setLocation(array(
  455. $this->person->fullname => "person/view/" . $this->person->user_id,
  456. $this->title => 0));
  457. return
  458. para("Confirm that you wish to delete this user from the system.")
  459. . $this->generateView($this->person)
  460. . form(
  461. form_hidden('edit[step]', 'perform')
  462. . form_submit("Delete")
  463. );
  464. }
  465. }
  466. /**
  467. * Approve new account creation
  468. */
  469. class PersonApproveNewAccount extends PersonView
  470. {
  471. var $person;
  472. function has_permission()
  473. {
  474. global $lr_session;
  475. if(!$this->person) {
  476. error_exit("That user does not exist");
  477. }
  478. return $lr_session->has_permission('person','approve', $this->person->user_id);
  479. }
  480. function process ()
  481. {
  482. $edit = $_POST['edit'];
  483. $this->title = 'Approve Account';
  484. if($edit['step'] == 'perform') {
  485. /* Actually do the approval on the 'perform' step */
  486. $this->perform( $edit );
  487. local_redirect("person/listnew");
  488. }
  489. if($this->person->status != 'new') {
  490. error_exit("That account has already been approved");
  491. }
  492. $dispositions = array(
  493. '---' => '- Select One -',
  494. 'approve_player' => 'Approved as Player',
  495. 'approve_visitor' => 'Approved as visitor account',
  496. 'delete' => 'Deleted silently',
  497. );
  498. $sth = $this->person->find_duplicates();
  499. $duplicates = '';
  500. while( $user = $sth->fetchObject('Person', array(LOAD_OBJECT_ONLY)) ) {
  501. $duplicates .= "<li>$user->firstname $user->lastname";
  502. $duplicates .= "[&nbsp;" . l("view", "person/view/$user->user_id") . "&nbsp;]";
  503. $dispositions["delete_duplicate:$user->user_id"] = "Deleted as duplicate of $user->firstname $user->lastname ($user->user_id)";
  504. $dispositions["merge_duplicate:$user->user_id"] = "Merged backwards into $user->firstname $user->lastname ($user->user_id)";
  505. }
  506. $approval_form =
  507. form_hidden('edit[step]', 'perform')
  508. . form_select('This user should be', 'edit[disposition]', '---', $dispositions)
  509. . form_submit("Submit");
  510. $this->setLocation(array(
  511. $this->person->fullname => "person/view/" . $this->person->user_id,
  512. $this->title => 0));
  513. if( strlen($duplicates) > 0 ) {
  514. $duplicates = para("<div class='warning'><br>The following users may be duplicates of this account:<ul>\n"
  515. . $duplicates
  516. . "</ul></div>");
  517. }
  518. return
  519. $duplicates
  520. . form( para($approval_form) )
  521. . $this->generateView($this->person);
  522. }
  523. function perform ( $edit )
  524. {
  525. global $lr_session;
  526. $disposition = $edit['disposition'];
  527. if($disposition == '---') {
  528. error_exit("You must select a disposition for this account");
  529. }
  530. list($disposition,$dup_id) = split(':',$disposition);
  531. switch($disposition) {
  532. case 'approve_player':
  533. $this->person->set('class','player');
  534. $this->person->set('status','inactive');
  535. if(! $this->person->generate_member_id() ) {
  536. error_exit("Couldn't get member ID allocation");
  537. }
  538. if( ! $this->person->save() ) {
  539. error_exit("Couldn't save new member activation");
  540. }
  541. $message = _person_mail_text('approved_body_player', array(
  542. '%fullname' => $this->person->fullname,
  543. '%username' => $this->person->username,
  544. '%memberid' => $this->person->member_id,
  545. '%url' => url(""),
  546. '%adminname' => variable_get('app_admin_name', 'Leaguerunner Admin'),
  547. '%site' => variable_get('app_name','Leaguerunner')));
  548. $rc = send_mail($this->person->email, $this->person->fullname,
  549. false, false, // from the administrator
  550. false, false, // no Cc
  551. _person_mail_text('approved_subject', array( '%username' => $this->person->username, '%site' => variable_get('app_name','Leaguerunner') )),
  552. $message);
  553. if($rc == false) {
  554. error_exit("Error sending email to " . $this->person->email);
  555. }
  556. return true;
  557. case 'approve_visitor':
  558. $this->person->set('class','visitor');
  559. $this->person->set('status','inactive');
  560. if( ! $this->person->save() ) {
  561. error_exit("Couldn't save new member activation");
  562. }
  563. $message = _person_mail_text('approved_body_visitor', array(
  564. '%fullname' => $this->person->fullname,
  565. '%username' => $this->person->username,
  566. '%url' => url(""),
  567. '%adminname' => variable_get('app_admin_name','Leaguerunner Admin'),
  568. '%site' => variable_get('app_name','Leaguerunner')));
  569. $rc = send_mail($this->person->email, $this->person->fullname,
  570. false, false, // from the administrator
  571. false, false, // no Cc
  572. _person_mail_text('approved_subject', array( '%username' => $this->person->username, '%site' => variable_get('app_name','Leaguerunner' ))),
  573. $message);
  574. if($rc == false) {
  575. error_exit("Error sending email to " . $this->person->email);
  576. }
  577. return true;
  578. case 'delete':
  579. if( ! $this->person->delete() ) {
  580. error_exit("Delete of user " . $this->person->fullname . " failed.");
  581. }
  582. return true;
  583. case 'delete_duplicate':
  584. $existing = person_load( array('user_id' => $dup_id) );
  585. $message = _person_mail_text('dup_delete_body', array(
  586. '%fullname' => $this->person->fullname,
  587. '%username' => $this->person->username,
  588. '%existingusername' => $existing->username,
  589. '%existingemail' => $existing->email,
  590. '%passwordurl' => variable_get('password_reset', url('person/forgotpassword')),
  591. '%adminname' => $lr_session->user->fullname,
  592. '%site' => variable_get('app_name','Leaguerunner')));
  593. $addresses = $names = array();
  594. $addresses[] = $this->person->email;
  595. $names[] = $this->person->fullname;
  596. if($this->person->email != $existing->email) {
  597. $addresses[] = $existing->email;
  598. $names[] = $this->person->fullname;
  599. }
  600. if( ! $this->person->delete() ) {
  601. error_exit("Delete of user " . $this->person->fullname . " failed.");
  602. }
  603. $rc = send_mail($addresses, $names,
  604. false, false, // from the administrator
  605. false, false, // no Cc
  606. _person_mail_text('dup_delete_subject', array( '%site' => variable_get('app_name', 'Leaguerunner') )),
  607. $message);
  608. if($rc == false) {
  609. error_exit("Error sending email to " . $this->person->email);
  610. }
  611. return true;
  612. // This is basically the same as the delete duplicate, except
  613. // that some old information (e.g. user ID) is preserved
  614. case 'merge_duplicate':
  615. $existing = person_load( array('user_id' => $dup_id) );
  616. $message = _person_mail_text('dup_merge_body', array(
  617. '%fullname' => $this->person->fullname,
  618. '%username' => $this->person->username,
  619. '%existingusername' => $existing->username,
  620. '%existingemail' => $existing->email,
  621. '%passwordurl' => variable_get('password_reset', url('person/forgotpassword')),
  622. '%adminname' => variable_get('app_admin_name','Leaguerunner Admin'),
  623. '%site' => variable_get('app_name','Leaguerunner')));
  624. $addresses = $names = array();
  625. $addresses[] = $this->person->email;
  626. $names[] = $this->person->fullname;
  627. if($this->person->email != $existing->email) {
  628. $addresses[] = $existing->email;
  629. $names[] = $this->person->fullname;
  630. }
  631. // Copy over almost all of the new data; there must be a better way
  632. $existing->set('status', 'active');
  633. $existing->set('username', $this->person->username);
  634. $existing->set('password', $this->person->password);
  635. $existing->set('firstname', $this->person->firstname);
  636. $existing->set('lastname', $this->person->lastname);
  637. $existing->set('email', $this->person->email);
  638. $existing->set('allow_publish_email', $this->person->allow_publish_email);
  639. $existing->set('home_phone', $this->person->home_phone);
  640. $existing->set('publish_home_phone', $this->person->publish_home_phone);
  641. $existing->set('work_phone', $this->person->work_phone);
  642. $existing->set('publish_work_phone', $this->person->publish_work_phone);
  643. $existing->set('mobile_phone', $this->person->mobile_phone);
  644. $existing->set('publish_mobile_phone', $this->person->publish_mobile_phone);
  645. $existing->set('addr_street', $this->person->addr_street);
  646. $existing->set('addr_city', $this->person->addr_city);
  647. $existing->set('addr_prov', $this->person->addr_prov);
  648. $existing->set('addr_country', $this->person->addr_country);
  649. $existing->set('addr_postalcode', $this->person->addr_postalcode);
  650. $existing->set('gender', $this->person->gender);
  651. $existing->set('birthdate', $this->person->birthdate);
  652. $existing->set('height', $this->person->height);
  653. $existing->set('skill_level', $this->person->skill_level);
  654. $existing->set('year_started', $this->person->year_started);
  655. $existing->set('shirtsize', $this->person->shirtsize);
  656. $existing->set('session_cookie', $this->person->session_cookie);
  657. $existing->set('has_dog', $this->person->has_dog);
  658. $existing->set('survey_completed', $this->person->survey_completed);
  659. $existing->set('willing_to_volunteer', $this->person->willing_to_volunteer);
  660. $existing->set('contact_for_feedback', $this->person->contact_for_feedback);
  661. $existing->set('last_login', $this->person->last_login);
  662. $existing->set('client_ip', $this->person->client_ip);
  663. if( !$existing->member_id) {
  664. $existing->generate_member_id();
  665. }
  666. if( ! $this->person->delete() ) {
  667. error_exit("Delete of user " . $this->person->fullname . " failed.");
  668. }
  669. if( ! $existing->save() ) {
  670. error_exit("Couldn't save new member information");
  671. }
  672. $rc = send_mail($addresses, $names,
  673. false, false, // from the administrator
  674. false, false, // no Cc
  675. _person_mail_text('dup_merge_subject', array( '%site' => variable_get('app_name', 'Leaguerunner') )),
  676. $message);
  677. if($rc == false) {
  678. error_exit("Error sending email to " . $this->person->email);
  679. }
  680. return true;
  681. default:
  682. error_exit("You must select a disposition for this account");
  683. }
  684. }
  685. }
  686. /**
  687. * Player edit handler
  688. */
  689. class PersonEdit extends Handler
  690. {
  691. var $person;
  692. function has_permission ()
  693. {
  694. global $lr_session;
  695. if(!$this->person) {
  696. error_exit("That user does not exist");
  697. }
  698. return $lr_session->has_permission('person','edit', $this->person->user_id);
  699. }
  700. function process ()
  701. {
  702. global $lr_session;
  703. $edit = $_POST['edit'];
  704. $this->title = 'Edit';
  705. switch($edit['step']) {
  706. case 'confirm':
  707. $rc = $this->generateConfirm( $this->person->user_id, $edit );
  708. break;
  709. case 'perform':
  710. $this->perform( $this->person, $edit );
  711. if($this->person->is_active()) {
  712. local_redirect('person/view/' . $this->person->user_id);
  713. }
  714. else {
  715. local_redirect('');
  716. }
  717. break;
  718. default:
  719. $edit = object2array($this->person);
  720. $rc = $this->generateForm($this->person->user_id, $edit, "Edit any of the following fields and click 'Submit' when done.");
  721. }
  722. return $rc;
  723. }
  724. function generateForm ( $id, &$formData, $instructions = "")
  725. {
  726. global $lr_session, $CONFIG;
  727. $output = <<<END_TEXT
  728. <script language="JavaScript" type="text/javascript">
  729. <!--
  730. function popup(url)
  731. {
  732. newwindow=window.open(url,'Leaguerunner Skill Rating Form','height=350,width=400,resizable=yes,scrollbars=yes')
  733. if (window.focus) {newwindow.focus()}
  734. return false;
  735. }
  736. function doNothing() {}
  737. // -->
  738. // </script>
  739. END_TEXT;
  740. $output .= form_hidden('edit[step]', 'confirm');
  741. $output .= para($instructions);
  742. $output .= para(
  743. "Note that email and phone publish settings below only apply to regular players. "
  744. . "Captains will always have access to view the phone numbers and email addresses of their confirmed players. "
  745. . "All Team Captains will also have their email address viewable by other players"
  746. );
  747. $privacy = variable_get('privacy_policy', 'http://www.ocua.ca/node/17');
  748. if($privacy) {
  749. $output .= para(
  750. 'If you have concerns about the data ' . variable_get('app_org_short_name', 'the league') . ' collects, please see our '
  751. . "<b><a href=\"$privacy\" target=\"_new\">Privacy Policy</a>.</b>"
  752. );
  753. }
  754. if($lr_session->has_permission('person', 'edit', $id, 'name') ) {
  755. $group .= form_textfield('First Name', 'edit[firstname]', $formData['firstname'], 25,100, 'First (and, if desired, middle) name.');
  756. $group .= form_textfield('Last Name', 'edit[lastname]', $formData['lastname'], 25,100);
  757. } else {
  758. $group .= form_item('Full Name', $formData['firstname'] . ' ' . $formData['lastname']);
  759. }
  760. if($lr_session->has_permission('person', 'edit', $id, 'username') ) {
  761. $group .= form_textfield('System Username', 'edit[username]', $formData['username'], 25,100, 'Desired login name.');
  762. } else {
  763. $group .= form_item('System Username', $formData['username'], 'Desired login name.');
  764. }
  765. if($lr_session->has_permission('person', 'edit', $id, 'password') ) {
  766. $group .= form_password('Password', 'edit[password_once]', '', 25,100, 'Enter your desired password.');
  767. $group .= form_password('Re-enter Password', 'edit[password_twice]', '', 25,100, 'Enter your desired password a second time to confirm it.');
  768. }
  769. $group .= form_select('Gender', 'edit[gender]', $formData['gender'], getOptionsFromEnum( 'person', 'gender'), 'Select your gender');
  770. $output .= form_group('Identity', $group);
  771. $group = form_textfield('Email Address', 'edit[email]', $formData['email'], 25, 100, 'Enter your preferred email address. This will be used by ' . variable_get('app_org_short_name', 'the league') . ' to correspond with you on league matters.');
  772. $group .= form_checkbox('Allow other players to view my email address','edit[allow_publish_email]','Y',($formData['allow_publish_email'] == 'Y'));
  773. $output .= form_group('Online Contact', $group);
  774. $group = form_textfield('Street and Number','edit[addr_street]',$formData['addr_street'], 25, 100, 'Number, street name, and apartment number if necessary');
  775. $group .= form_textfield('City','edit[addr_city]',$formData['addr_city'], 25, 100, 'Name of city');
  776. /* TODO: evil. Need to allow Americans to use this at some point in
  777. * time... */
  778. $group .= form_select('Province', 'edit[addr_prov]', $formData['addr_prov'], getProvinceNames(), 'Select a province/state from the list');
  779. $group .= form_select('Country', 'edit[addr_country]', $formData['addr_country'], getCountryNames(), 'Select a country from the list');
  780. $group .= form_textfield('Postal Code', 'edit[addr_postalcode]', $formData['addr_postalcode'], 8, 7, 'Please enter a correct postal code matching the address above. ' . variable_get('app_org_short_name', 'the league') . ' uses this information to help locate new fields near its members.');
  781. $output .= form_group('Street Address', $group);
  782. $group = form_textfield('Home', 'edit[home_phone]', $formData['home_phone'], 25, 100, 'Enter your home telephone number');
  783. $group .= form_checkbox('Allow other players to view home number','edit[publish_home_phone]','Y',($formData['publish_home_phone'] == 'Y'));
  784. $group .= form_textfield('Work', 'edit[work_phone]', $formData['work_phone'], 25, 100, 'Enter your work telephone number (optional)');
  785. $group .= form_checkbox('Allow other players to view work number','edit[publish_work_phone]','Y',($formData['publish_work_phone'] == 'Y'));
  786. $group .= form_textfield('Mobile', 'edit[mobile_phone]', $formData['mobile_phone'], 25, 100, 'Enter your cell or pager number (optional)');
  787. $group .= form_checkbox('Allow other players to view mobile number','edit[publish_mobile_phone]','Y',($formData['publish_mobile_phone'] == 'Y'));
  788. $output .= form_group('Telephone Numbers', $group);
  789. $player_classes = array(
  790. 'player' => 'Player',
  791. 'visitor' => 'Non-player account');
  792. if(! $formData['class'] ) {
  793. $formData['class'] = 'visitor';
  794. }
  795. if($lr_session->has_permission('person', 'edit', $id, 'class') ) {
  796. $player_classes['administrator'] = 'Leaguerunner administrator';
  797. $player_classes['volunteer'] = 'Volunteer';
  798. }
  799. # Volunteers can unset themselves as volunteer if they wish.
  800. if( $formData['class'] == 'volunteer' ) {
  801. $player_classes['volunteer'] = 'Volunteer';
  802. }
  803. $group = form_radiogroup('Account Type', 'edit[class]', $formData['class'], $player_classes );
  804. if($lr_session->has_permission('person', 'edit', $id, 'status') ) {
  805. $group .= form_select('Account Status','edit[status]', $formData['status'], getOptionsFromEnum('person','status'));
  806. }
  807. $output .= form_group('Account Information', $group);
  808. $group = form_select('Skill Level', 'edit[skill_level]', $formData['skill_level'],
  809. getOptionsFromRange(1, 10),
  810. "Please use the questionnaire to <a href=\"" . $CONFIG['paths']['base_url'] . "/data/rating.html\" target='_new'>calculate your rating</a>"
  811. );
  812. $thisYear = strftime('%Y', time());
  813. $group .= form_select('Year Started', 'edit[year_started]', $formData['year_started'],
  814. getOptionsFromRange(1986, $thisYear, 'reverse'), 'The year you started playing Ultimate in this league.');
  815. $group .= form_select_date('Birthdate', 'edit[birth]', $formData['birthdate'], ($thisYear - 75), ($thisYear - 5), 'Please enter a correct birthdate; having accurate information is important for insurance purposes');
  816. $group .= form_textfield('Height','edit[height]',$formData['height'], 4, 4, 'Please enter your height in inches (5 feet is 60 inches; 6 feet is 72 inches). This is used to help generate even teams for hat leagues.');
  817. $group .= form_select('Shirt Size','edit[shirtsize]', $formData['shirtsize'], getShirtSizes());
  818. if (variable_get('dog_questions', 1)) {
  819. $group .= form_radiogroup('Has Dog', 'edit[has_dog]', $formData['has_dog'], array(
  820. 'Y' => 'Yes, I have a dog I will be bringing to games',
  821. 'N' => 'No, I will not be bringing a dog to games'));
  822. }
  823. $group .= form_radiogroup('Can ' . variable_get('app_org_short_name', 'the league') . ' contact you with a survey about volunteering?', 'edit[willing_to_volunteer]', $formData['willing_to_volunteer'], array(
  824. 'Y' => 'Yes',
  825. 'N' => 'No'));
  826. $group .= form_radiogroup('From time to time, ' . variable_get('app_org_short_name', 'the league') .
  827. ' would like to contact members with information on our programs and to solicit feedback. ' .
  828. 'Can ' . variable_get('app_org_short_name', 'the league') . ' contact you in this regard? ',
  829. 'edit[contact_for_feedback]', $formData['contact_for_feedback'],
  830. array('Y' => 'Yes',
  831. 'N' => 'No'));
  832. $output .= form_group('Player and Skill Information', $group);
  833. $this->setLocation(array(
  834. $formData['fullname'] => "person/view/$id",
  835. $this->title => 0));
  836. $output .= para(form_submit('submit') . form_reset('reset'));
  837. return form($output, 'post', null, 'id="player_form"');
  838. }
  839. function generateConfirm ( $id, $edit = array() )
  840. {
  841. global $lr_session;
  842. $dataInvalid = $this->isDataInvalid( $id, $edit );
  843. if($dataInvalid) {
  844. error_exit($dataInvalid . "<br>Please use your back button to return to the form, fix these errors, and try again");
  845. }
  846. $output = para("Confirm that the data below is correct and click 'Submit' to make your changes.");
  847. $output .= form_hidden('edit[step]', 'perform');
  848. $group = '';
  849. if($lr_session->has_permission('person', 'edit', $id, 'name') ) {
  850. $group .= form_item('First Name',
  851. form_hidden('edit[firstname]',$edit['firstname']) . $edit['firstname']);
  852. $group .= form_item('Last Name',
  853. form_hidden('edit[lastname]',$edit['lastname']) . $edit['lastname']);
  854. }
  855. if($lr_session->has_permission('person', 'edit', $id, 'username') ) {
  856. $group .= form_item('System Username',
  857. form_hidden('edit[username]',$edit['username']) . $edit['username']);
  858. }
  859. if($lr_session->has_permission('person', 'edit', $id, 'password') ) {
  860. $group .= form_item('Password',
  861. form_hidden('edit[password_once]', $edit['password_once'])
  862. . form_hidden('edit[password_twice]', $edit['password_twice'])
  863. . '<i>(entered)</i>');
  864. }
  865. $group .= form_item('Gender', form_hidden('edit[gender]',$edit['gender']) . $edit['gender']);
  866. $output .= form_group('Identity', $group);
  867. $group = form_item('Email Address',
  868. form_hidden('edit[email]',$edit['email']) . $edit['email']);
  869. $group .= form_item('Show email to other players',
  870. form_hidden('edit[allow_publish_email]',$edit['allow_publish_email']) . $edit['allow_publish_email']);
  871. $output .= form_group('Online Contact', $group);
  872. $group = form_item('',
  873. form_hidden('edit[addr_street]',$edit['addr_street'])
  874. . form_hidden('edit[addr_city]',$edit['addr_city'])
  875. . form_hidden('edit[addr_prov]',$edit['addr_prov'])
  876. . form_hidden('edit[addr_country]',$edit['addr_country'])
  877. . form_hidden('edit[addr_postalcode]',$edit['addr_postalcode'])
  878. . "{$edit['addr_street']}<br>{$edit['addr_city']}, {$edit['addr_prov']}, {$edit['addr_country']}<br>{$edit['addr_postalcode']}");
  879. $output .= form_group('Street Address', $group);
  880. $group = '';
  881. foreach( array('home','work','mobile') as $location) {
  882. if($edit["${location}_phone"]) {
  883. $group .= form_item(ucfirst($location),
  884. form_hidden("edit[${location}_phone]", $edit["${location}_phone"])
  885. . $edit["${location}_phone"]);
  886. if($edit["publish_${location}_phone"] == 'Y') {
  887. $publish_info = "yes";
  888. $publish_info .= form_hidden("edit[publish_${location}_phone]", 'Y');
  889. } else {
  890. $publish_info = "no";
  891. }
  892. $group .= form_item("Allow other players to view $location number", $publish_info);
  893. }
  894. }
  895. $output .= form_group('Telephone Numbers', $group);
  896. $group = form_item("Account Class", form_hidden('edit[class]',$edit['class']) . $edit['class']);
  897. if($lr_session->has_permission('person', 'edit', $id, 'status') ) {
  898. $group .= form_item("Account Status", form_hidden('edit[status]',$edit['status']) . $edit['status']);
  899. }
  900. $output .= form_group('Account Information', $group);
  901. $levels = getOptionsForSkill();
  902. $group = form_item("Skill Level", form_hidden('edit[skill_level]',$edit['skill_level']) . $levels[$edit['skill_level']]);
  903. $group .= form_item("Year Started", form_hidden('edit[year_started]',$edit['year_started']) . $edit['year_started']);
  904. $group .= form_item("Birthdate",
  905. form_hidden('edit[birth][year]',$edit['birth']['year'])
  906. . form_hidden('edit[birth][month]',$edit['birth']['month'])
  907. . form_hidden('edit[birth][day]',$edit['birth']['day'])
  908. . $edit['birth']['year'] . " / " . $edit['birth']['month'] . " / " . $edit['birth']['day']);
  909. if($edit['height']) {
  910. $group .= form_item("Height", form_hidden('edit[height]',$edit['height']) . $edit['height'] . " inches");
  911. }
  912. $group .= form_item("Shirt Size", form_hidden('edit[shirtsize]',$edit['shirtsize']) . $edit['shirtsize']);
  913. if (variable_get('dog_questions', 1)) {
  914. $group .= form_item("Has dog", form_hidden('edit[has_dog]',$edit['has_dog']) . $edit['has_dog']);
  915. }
  916. $group .= form_item('Can ' . variable_get('app_org_short_name', 'the league') . ' contact you with a survey about volunteering?', form_hidden('edit[willing_to_volunteer]',$edit['willing_to_volunteer']) . $edit['willing_to_volunteer']);
  917. $group .= form_item('From time to time, ' . variable_get('app_org_short_name', 'the league') .
  918. ' would like to contact members with information on our programs and to solicit feedback. ' .
  919. 'Can ' . variable_get('app_org_short_name', 'the league') . ' contact you in this regard? ',
  920. form_hidden('edit[contact_for_feedback]',$edit['contact_for_feedback']) . $edit['contact_for_feedback']);
  921. $output .= form_group('Player and Skill Information', $group);
  922. $output .= para(form_submit('submit') . form_reset('reset'));
  923. $this->setLocation(array(
  924. $edit['firstname'] . " " . $edit['lastname'] => "person/view/$id",
  925. $this->title => 0));
  926. return form($output);
  927. }
  928. function perform ( $person, $edit = array() )
  929. {
  930. global $lr_session;
  931. $dataInvalid = $this->isDataInvalid( $person->user_id, $edit );
  932. if($dataInvalid) {
  933. error_exit($dataInvalid . "<br>Please use your back button to return to the form, fix these errors, and try again");
  934. }
  935. if($edit['username'] && $lr_session->has_permission('person', 'edit', $this->person->user_id, 'username') ) {
  936. $person->set('username', $edit['username']);
  937. }
  938. /* EVIL HACK
  939. * If this person is currently a 'visitor', it does not have a
  940. * member number, so if we move it to another class, it needs
  941. * to be given one. We do this by forcing its status to 'new' and
  942. * requiring it be reapproved. Ugly hack, but since
  943. * we're likely to scrutinize non-player accounts less than player
  944. * accounts, it's necessary.
  945. */
  946. if( ($person->class == 'visitor') && ($edit['class'] == 'player') ) {
  947. $person->set('status','new');
  948. $person->set('class','player');
  949. $status_changed = true;
  950. }
  951. if($edit['class'] && $lr_session->has_permission('person', 'edit', $this->person->user_id, 'class') ) {
  952. $person->set('class', $edit['class']);
  953. }
  954. if($edit['status'] && $lr_session->has_permission('person', 'edit', $this->person->user_id, 'status') ) {
  955. $person->set('status',$edit['status']);
  956. }
  957. $person->set('email', $edit['email']);
  958. $person->set('allow_publish_email', $edit['allow_publish_email']);
  959. foreach(array('home_phone','work_phone','mobile_phone') as $type) {
  960. $num = $edit[$type];
  961. if(strlen($num)) {
  962. $person->set($type, clean_telephone_number($num));
  963. } else {
  964. $person->set($type, null);
  965. }
  966. $person->set('publish_' . $type, $edit['publish_' . $type] ? 'Y' : 'N');
  967. }
  968. if($lr_session->has_permission('person', 'edit', $this->person->user_id, 'name') ) {
  969. $person->set('firstname', $edit['firstname']);
  970. $person->set('lastname', $edit['lastname']);
  971. }
  972. $person->set('addr_street', $edit['addr_street']);
  973. $person->set('addr_city', $edit['addr_city']);
  974. $person->set('addr_prov', $edit['addr_prov']);
  975. $person->set('addr_country', $edit['addr_country']);
  976. $postcode = $edit['addr_postalcode'];
  977. if(strlen($postcode) == 6) {
  978. $foo = substr($postcode,0,3) . " " . substr($postcode,3);
  979. $postcode = $foo;
  980. }
  981. $person->set('addr_postalcode', $edit['addr_postalcode']);
  982. $person->set('birthdate', join("-",array(
  983. $edit['birth']['year'],
  984. $edit['birth']['month'],
  985. $edit['birth']['day'])));
  986. if($edit['height']) {
  987. $person->set('height', $edit['height']);
  988. }
  989. $person->set('shirtsize', $edit['shirtsize']);
  990. $person->set('gender', $edit['gender']);
  991. $person->set('skill_level', $edit['skill_level']);
  992. $person->set('year_started', $edit['year_started']);
  993. if (variable_get('dog_questions', 1)) {
  994. $person->set('has_dog', $edit['has_dog']);
  995. }
  996. $person->set('willing_to_volunteer', $edit['willing_to_volunteer']);
  997. $person->set('contact_for_feedback', $edit['contact_for_feedback']);
  998. if( ! $person->save() ) {
  999. error_exit("Internal error: couldn't save changes");
  1000. } else {
  1001. /* EVIL HACK
  1002. * If a user changes their own status from visitor to player, they
  1003. * will get logged out, so we need to warn them of this fact.
  1004. */
  1005. if($status_changed) {
  1006. print theme_header("Edit Account");
  1007. print theme_body($this->breadcrumbs);
  1008. print "<h1>Edit Account</h1>";
  1009. print para(
  1010. "You have requested to change your account status to 'Player'. As such, your account is now being held for one of the administrators to approve. "
  1011. . 'Once your account is approved, you will receive an email informing you of your new ' . variable_get('app_org_short_name', 'League') . ' member number. '
  1012. . 'You will then be able to log in once again with your username and password.');
  1013. print theme_footer();
  1014. exit;
  1015. }
  1016. }
  1017. return true;
  1018. }
  1019. function isDataInvalid ( $id, $edit = array() )
  1020. {
  1021. global $lr_session;
  1022. $errors = "";
  1023. if($lr_session->has_permission('person','edit',$id, 'name')) {
  1024. if( ! validate_name_input($edit['firstname']) || ! validate_name_input($edit['lastname'])) {
  1025. $errors .= "\n<li>You can only use letters, numbers, spaces, and the characters - ' and . in first and last names";
  1026. }
  1027. }
  1028. if($lr_session->has_permission('person','edit',$id, 'username')) {
  1029. if( ! validate_name_input($edit['username']) ) {
  1030. $errors .= "\n<li>You can only use letters, numbers, spaces, and the characters - ' and . in usernames";
  1031. }
  1032. $user = person_load( array('username' => $edit['username']) );
  1033. # TODO: BUG: need to check that $user->user_id != current id
  1034. if( $user && !$lr_session->is_admin()) {
  1035. error_exit("A user with that username already exists; please go back and try again");
  1036. }
  1037. }
  1038. if ( ! validate_email_input($edit['email']) ) {
  1039. $errors .= "\n<li>You must supply a valid email address";
  1040. }
  1041. if( !validate_nonblank($edit['home_phone']) &&
  1042. !validate_nonblank($edit['work_phone']) &&
  1043. !validate_nonblank($edit['mobile_phone']) ) {
  1044. $errors .= "\n<li>You must supply at least one valid telephone number. Please supply area code, number and (if any) extension.";
  1045. }
  1046. if(validate_nonblank($edit['home_phone']) && !validate_telephone_input($edit['home_phone'])) {
  1047. $errors .= "\n<li>Home telephone number is not valid. Please supply area code, number and (if any) extension.";
  1048. }
  1049. if(validate_nonblank($edit['work_phone']) && !validate_telephone_input($edit['work_phone'])) {
  1050. $errors .= "\n<li>Work telephone number is not valid. Please supply area code, number and (if any) extension.";
  1051. }
  1052. if(validate_nonblank($edit['mobile_phone']) && !validate_telephone_input($edit['mobile_phone'])) {
  1053. $errors .= "\n<li>Mobile telephone number is not valid. Please supply area code, number and (if any) extension.";
  1054. }
  1055. $address_errors = validate_address(
  1056. $edit['addr_street'],
  1057. $edit['addr_city'],
  1058. $edit['addr_prov'],
  1059. $edit['addr_postalcode'],
  1060. $edit['addr_country']);
  1061. if( count($address_errors) > 0) {
  1062. $errors .= "\n<li>" . join("\n<li>", $address_errors);
  1063. }
  1064. if( !preg_match("/^[mf]/i",$edit['gender'] ) ) {
  1065. $errors .= "\n<li>You must select either male or female for gender.";
  1066. }
  1067. if( !validate_date_input($edit['birth']['year'], $edit['birth']['month'], $edit['birth']['day']) ) {
  1068. $errors .= "\n<li>You must provide a valid birthdate";
  1069. }
  1070. if( validate_nonblank($edit['height']) ) {
  1071. if( !$lr_session->is_admin() && ( ($edit['height'] < 36) || ($edit['height'] > 84) )) {
  1072. $errors .= "\n<li>Please enter a reasonable and valid value for your height.";
  1073. }
  1074. }
  1075. if( $edit['skill_level'] < 1 || $edit['skill_level'] > 10 ) {
  1076. $errors .= "\n<li>You must select a skill level between 1 and 10. You entered " . $edit['skill_level'];
  1077. }
  1078. $current = localtime(time(),1);
  1079. $this_year = $current['tm_year'] + 1900;
  1080. if( $edit['year_started'] > $this_year ) {
  1081. $errors .= "\n<li>Year started must be before current year.";
  1082. }
  1083. if( $edit['year_started'] < 1986 ) {
  1084. $errors .= "\n<li>Year started must be after 1986. For the number of people who started playing before then, I don't think it matters if you're listed as having played 17 years or 20, you're still old. :)";
  1085. }
  1086. $yearDiff = $edit['year_started'] - $edit['birth']['year'];
  1087. if( $yearDiff < 8) {
  1088. $errors .= "\n<li>You can't have started playing when you were $yearDiff years old! Please correct your birthdate, or your starting year";
  1089. }
  1090. if(strlen($errors) > 0) {
  1091. return $errors;
  1092. } else {
  1093. return false;
  1094. }
  1095. }
  1096. }
  1097. /**
  1098. * Player create handler
  1099. */
  1100. class PersonCreate extends PersonEdit
  1101. {
  1102. var $person;
  1103. function has_permission ()
  1104. {
  1105. global $lr_session;
  1106. return $lr_session->has_permission('person','create');
  1107. }
  1108. function checkPrereqs( $next )
  1109. {
  1110. return false;
  1111. }
  1112. function process ()
  1113. {
  1114. $edit = $_POST['edit'];
  1115. $this->title = 'Create Account';
  1116. $id = 'new';
  1117. switch($edit['step']) {
  1118. case 'confirm':
  1119. $rc = $this->generateConfirm( $id, $edit );
  1120. break;
  1121. case 'perform':
  1122. $this->person = new Person;
  1123. $this->person->user_id = $id;
  1124. return $this->perform( $this->person, $edit );
  1125. default:
  1126. $edit = array();
  1127. $rc = $this->generateForm( $id, $edit, "To create a new account, fill in all the fields below and click 'Submit' when done. Your account will be placed on hold until approved by an administrator. Once approved, you will be allocated a membership number, and have full access to the system.<p><b>NOTE</b> If you already have an account from a previous season, DO NOT CREATE ANOTHER ONE! Instead, please <a href=\"" . variable_get('password_reset', url('person/forgotpassword')) . "\">follow these instructions</a> to gain access to your account.");
  1128. }
  1129. $this->setLocation(array( $this->title => 0));
  1130. return $rc;
  1131. }
  1132. function perform ( $person, $edit = array())
  1133. {
  1134. global $lr_session;
  1135. if( ! validate_name_input($edit['username']) ) {
  1136. $errors .= "\n<li>You can only use letters, numbers, spaces, and the characters - ' and . in usernames";
  1137. }
  1138. $existing_user = person_load( array('username' => $edit['username']) );
  1139. if( $existing_user ) {
  1140. error_exit("A user with that username already exists; please go back and try again");
  1141. }
  1142. if($edit['password_once'] != $edit['password_twice']) {
  1143. error_exit("First and second entries of password do not match");
  1144. }
  1145. $crypt_pass = md5($edit['password_once']);
  1146. $person->set('username', $edit['username']);
  1147. $person->set('firstname', $edit['firstname']);
  1148. $person->set('lastname', $edit['lastname']);
  1149. $person->set('password', $crypt_pass);
  1150. $rc = parent::perform( $person, $edit );
  1151. if( $rc === false ) {
  1152. return false;
  1153. } else {
  1154. return para(
  1155. "Thank you for creating an account. It is now being held for one of the administrators to approve. "
  1156. . "Once your account is approved, you will receive an email informing you. "
  1157. . "You will then be able to log in with your username and password."
  1158. );
  1159. }
  1160. }
  1161. }
  1162. /**
  1163. * Account reactivation
  1164. *
  1165. * Accounts must be periodically reactivated to ensure that they are
  1166. * reasonably up-to-date.
  1167. */
  1168. class PersonActivate extends PersonEdit
  1169. {
  1170. var $person;
  1171. function checkPrereqs ( $ignored )
  1172. {
  1173. return false;
  1174. }
  1175. /**
  1176. * Check to see if this user can activate themselves.
  1177. * This is only possible if the user is in the 'inactive' status. This
  1178. * also means that the user can't have a valid session.
  1179. */
  1180. function has_permission ()
  1181. {
  1182. global $lr_session;
  1183. if($lr_session->is_valid()) {
  1184. return false;
  1185. }
  1186. if ($lr_session->attr_get('status') != 'inactive') {
  1187. error_exit("You do…

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