Completed
Push — develop ( a1a3a0 )
by
unknown
02:19
created

ForumRole::augmentDatabase()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 21
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 21
rs 9.3142
cc 3
eloc 18
nc 2
nop 0
1
<?php
2
/**
3
 * ForumRole
4
 *
5
 * This decorator adds the needed fields and methods to the {@link Member}
6
 * object.
7
 *
8
 * @package forum
9
 */
10
class ForumRole extends DataExtension {
11
12
	/**
13
	 * Update the database schema as required by this extension
14
	 */
15
	public function augmentDatabase() {
16
		$exist = DB::table_list();
17
 		if(!empty($exist) && array_search('ForumMember', $exist) !== false) {
18
			DB::query( "UPDATE \"Member\", \"ForumMember\" " .
19
				"SET \"Member\".\"ClassName\" = 'Member'," .
20
				"\"Member\".\"ForumRank\" = \"ForumMember\".\"ForumRank\"," .
21
				"\"Member\".\"Occupation\" = \"ForumMember\".\"Occupation\"," .
22
				"\"Member\".\"Country\" = \"ForumMember\".\"Country\"," .
23
				"\"Member\".\"Nickname\" = \"ForumMember\".\"Nickname\"," .
24
				"\"Member\".\"FirstNamePublic\" = \"ForumMember\".\"FirstNamePublic\"," .
25
				"\"Member\".\"SurnamePublic\" = \"ForumMember\".\"SurnamePublic\"," .
26
				"\"Member\".\"OccupationPublic\" = \"ForumMember\".\"OccupationPublic\"," .
27
				"\"Member\".\"CountryPublic\" = \"ForumMember\".\"CountryPublic\"," .
28
				"\"Member\".\"EmailPublic\" = \"ForumMember\".\"EmailPublic\"," .
29
				"\"Member\".\"AvatarID\" = \"ForumMember\".\"AvatarID\"," .
30
				"\"Member\".\"LastViewed\" = \"ForumMember\".\"LastViewed\"" .
31
				"WHERE \"Member\".\"ID\" = \"ForumMember\".\"ID\""
32
			);
33
			echo("<div style=\"padding:5px; color:white; background-color:blue;\">" . _t('ForumRole.TRANSFERSUCCEEDED','The data transfer has succeeded. However, to complete it, you must delete the ForumMember table. To do this, execute the query \"DROP TABLE \'ForumMember\'\".') . "</div>" );
34
		}
35
	}
36
37
	private static $db =  array(
38
		'ForumRank' => 'Varchar',
39
		'Occupation' => 'Varchar',
40
		'Company' => 'Varchar',
41
		'City' => 'Varchar',
42
		'Country' => 'Varchar',
43
		'Nickname' => 'Varchar',
44
		'FirstNamePublic' => 'Boolean',
45
		'SurnamePublic' => 'Boolean',
46
		'OccupationPublic' => 'Boolean',
47
		'CompanyPublic' => 'Boolean',
48
		'CityPublic' => 'Boolean',
49
		'CountryPublic' => 'Boolean',
50
		'EmailPublic' => 'Boolean',
51
		'LastViewed' => 'SS_Datetime',
52
		'Signature' => 'Text',
53
		'ForumStatus' => 'Enum("Normal, Banned, Ghost", "Normal")',
54
		'SuspendedUntil' => 'Date'
55
	);
56
57
	private static $has_one = array(
58
		'Avatar' => 'Image'
59
	);
60
61
	private static $has_many = array(
62
		'ForumPosts' => 'Post'
63
	);
64
65
	private static $belongs_many_many = array(
66
		'ModeratedForums' => 'Forum'
67
	);
68
69
	private static $defaults = array(
70
		'ForumRank' => 'Community Member'
71
	);
72
73
	private static $searchable_fields = array(
74
		'Nickname' => true
75
	);
76
77
	private static $indexes = array(
78
		'Nickname' => true
79
	);
80
81
	private static $field_labels = array(
82
		'SuspendedUntil' => "Suspend this member from writing on forums until the specified date"
83
	);
84
85
	public function onBeforeDelete() {
86
		parent::onBeforeDelete();
87
88
		$avatar = $this->owner->Avatar();
89
		if($avatar && $avatar->exists()) {
90
			$avatar->delete();
91
		}
92
	}
93
94
	function ForumRank() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
95
		$moderatedForums = $this->owner->ModeratedForums();
96
		if($moderatedForums && $moderatedForums->Count() > 0) return _t('MODERATOR','Forum Moderator');
97
		else return $this->owner->getField('ForumRank');
98
	}
99
100
	function FirstNamePublic() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
101
		return $this->owner->FirstNamePublic || Permission::check('ADMIN');
102
	}
103
	function SurnamePublic() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
104
		return $this->owner->SurnamePublic || Permission::check('ADMIN');
105
	}
106
	function OccupationPublic() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
107
		return $this->owner->OccupationPublic || Permission::check('ADMIN');
108
	}
109
	function CompanyPublic() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
110
		return $this->owner->CompanyPublic || Permission::check('ADMIN');
111
	}
112
	function CityPublic() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
113
		return $this->owner->CityPublic || Permission::check('ADMIN');
114
	}
115
	function CountryPublic() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
116
		return $this->owner->CountryPublic || Permission::check('ADMIN');
117
	}
118
	function EmailPublic() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
119
		return $this->owner->EmailPublic || Permission::check('ADMIN');
120
	}
121
	/**
122
	 * Run the Country code through a converter to get the proper Country Name
123
	 */
124
	function FullCountry() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
125
		$locale = new Zend_Locale();
126
		$locale->setLocale($this->owner->Country);
127
		return $locale->getRegion();
128
	}
129
	function NumPosts() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
130
		if(is_numeric($this->owner->ID)) {
131
			return $this->owner->ForumPosts()->Count();
132
		} else {
133
			return 0;
134
		}
135
	}
136
	
137
	/**
138
	 * Checks if the current user is a moderator of the
139
	 * given forum by looking in the moderator ID list.
140
	 *
141
	 * @param Forum object to check
142
	 * @return boolean
143
	 */
144
	function isModeratingForum($forum) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
145
		$moderatorIds = $forum->Moderators() ? $forum->Moderators()->getIdList() : array();
146
		return in_array($this->owner->ID, $moderatorIds);
147
	}
148
149
	function Link() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
150
		return "ForumMemberProfile/show/" . $this->owner->ID;
151
	}
152
153
154
	/**
155
	 * Get the fields needed by the forum module
156
	 *
157
	 * @param bool $showIdentityURL Should a field for an OpenID or an i-name
158
	 *                              be shown (always read-only)?
159
	 * @return FieldList Returns a FieldList containing all needed fields for
160
	 *                  the registration of new users
161
	 */
162
	function getForumFields($showIdentityURL = false, $addmode = false) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
163
		$gravatarText = (DataObject::get_one("ForumHolder", "\"AllowGravatars\" = 1")) ? '<small>'. _t('ForumRole.CANGRAVATAR', 'If you use Gravatars then leave this blank') .'</small>' : "";
164
165
		//Sets the upload folder to the Configurable one set via the ForumHolder or overridden via Config::inst()->update().
166
		$avatarField = new FileField('Avatar', _t('ForumRole.AVATAR','Avatar Image') .' '. $gravatarText);
167
		$avatarField->setFolderName(Config::inst()->get('ForumHolder','avatars_folder'));
168
		$avatarField->getValidator()->setAllowedExtensions(array('jpg', 'jpeg', 'gif', 'png'));
169
170
		$personalDetailsFields = new CompositeField(
171
			new HeaderField("PersonalDetails", _t('ForumRole.PERSONAL','Personal Details')),
172
	
173
			new LiteralField("Blurb","<p id=\"helpful\">" . _t('ForumRole.TICK', 'Tick the fields to show in public profile') . "</p>"),
174
	
175
			new TextField("Nickname", _t('ForumRole.NICKNAME','Nickname')),
176
			new CheckableOption("FirstNamePublic", new TextField("FirstName", _t('ForumRole.FIRSTNAME','First name'))),
177
			new CheckableOption("SurnamePublic", new TextField("Surname", _t('ForumRole.SURNAME','Surname'))),
178
			new CheckableOption("OccupationPublic", new TextField("Occupation", _t('ForumRole.OCCUPATION','Occupation')), true),
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
179
			new CheckableOption('CompanyPublic', new TextField('Company', _t('ForumRole.COMPANY', 'Company')), true),
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
180
			new CheckableOption('CityPublic', new TextField('City', _t('ForumRole.CITY', 'City')), true),
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
181
			new CheckableOption("CountryPublic", new ForumCountryDropdownField("Country", _t('ForumRole.COUNTRY','Country')), true),
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
182
			new CheckableOption("EmailPublic", new EmailField("Email", _t('ForumRole.EMAIL','Email'))),
183
			new ConfirmedPasswordField("Password", _t('ForumRole.PASSWORD','Password')),
184
			$avatarField
185
		);
186
		// Don't show 'forum rank' at registration
187
		if(!$addmode) {
188
			$personalDetailsFields->push(
189
				new ReadonlyField("ForumRank", _t('ForumRole.RATING','User rating'))
190
			);
191
		}
192
		$personalDetailsFields->setID('PersonalDetailsFields');
193
		
194
		$fieldset = new FieldList(
195
			$personalDetailsFields
196
		);
197
198
		if($showIdentityURL) {
199
			$fieldset->insertBefore(
200
				new ReadonlyField('IdentityURL', _t('ForumRole.OPENIDINAME','OpenID/i-name')),
201
				'Password'
0 ignored issues
show
Documentation introduced by
'Password' is of type string, but the function expects a object<FormField>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
202
			);
203
			$fieldset->insertAfter(
204
				new LiteralField(
205
					'PasswordOptionalMessage',
206
					'<p>' . _t('ForumRole.PASSOPTMESSAGE','Since you provided an OpenID respectively an i-name the password is optional. If you enter one, you will be able to log in also with your e-mail address.') . '</p>'
207
				),
208
				'IdentityURL'
0 ignored issues
show
Documentation introduced by
'IdentityURL' is of type string, but the function expects a object<FormField>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
209
			);
210
		}
211
212
		if($this->owner->IsSuspended()) {
213
			$fieldset->insertAfter(
214
				new LiteralField(
215
					'SuspensionNote', 
216
					'<p class="message warning suspensionWarning">' . $this->ForumSuspensionMessage() . '</p>'
217
				),
218
				'Blurb'
0 ignored issues
show
Documentation introduced by
'Blurb' is of type string, but the function expects a object<FormField>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
219
			);
220
		}
221
		
222
		$this->owner->extend('updateForumFields', $fieldset);
223
224
		return $fieldset;
225
	}
226
	
227
	/**
228
	 * Get the fields needed by the forum module
229
	 *
230
	 * @param bool $needPassword Should a password be required?
231
	 * @return Validator Returns a Validator for the fields required for the
232
	 * 								registration of new users
233
	 */
234
	function getForumValidator($needPassword = true) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
235
		if ($needPassword) {
236
			$validator = new RequiredFields("Nickname", "Email", "Password");
237
		} else {
238
			$validator = new RequiredFields("Nickname", "Email");
239
		}
240
		$this->owner->extend('updateForumValidator', $validator);
241
242
		return $validator;
243
	}
244
245
	function updateCMSFields(FieldList $fields) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
246
		$allForums = DataObject::get('Forum');
247
		$fields->removeByName('ModeratedForums');
248
		$fields->addFieldToTab('Root.ModeratedForums', new CheckboxSetField('ModeratedForums', _t('ForumRole.MODERATEDFORUMS', 'Moderated forums'), ($allForums->exists() ? $allForums->map('ID', 'Title') : array())));
249
		$suspend = $fields->dataFieldByName('SuspendedUntil');
250
		$suspend->setConfig('showcalendar', true);
0 ignored issues
show
Bug introduced by
The method setConfig() does not exist on FormField. Did you maybe mean config()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
251
		if(Permission::checkMember($this->owner->ID, "ACCESS_FORUM")) {
252
			$avatarField = new FileField('Avatar', _t('ForumRole.UPLOADAVATAR', 'Upload avatar'));
253
			$avatarField->getValidator()->setAllowedExtensions(array('jpg', 'jpeg', 'gif', 'png'));
254
255
			$fields->addFieldToTab('Root.Forum', $avatarField);
256
			$fields->addFieldToTab('Root.Forum',new DropdownField("ForumRank", _t('ForumRole.FORUMRANK', "User rating"), array(
257
				"Community Member" => _t('ForumRole.COMMEMBER'),
258
				"Administrator" => _t('ForumRole.ADMIN','Administrator'),
259
				"Moderator" => _t('ForumRole.MOD','Moderator')
260
			)));
261
			$fields->addFieldToTab('Root.Forum', $this->owner->dbObject('ForumStatus')->scaffoldFormField());
262
		}
263
	}
264
	
265
	public function IsSuspended() {
266
		if($this->owner->SuspendedUntil) {
267
			return strtotime(SS_Datetime::now()->Format('Y-m-d')) < strtotime($this->owner->SuspendedUntil);
268
		} else {
269
			return false; 
270
		}
271
	}
272
273
	public function IsBanned() {
274
		return $this->owner->ForumStatus == 'Banned';
275
	}
276
277
	public function IsGhost() {
278
		return $this->owner->ForumStatus == 'Ghost' && $this->owner->ID !== Member::currentUserID();
279
	}
280
281
	/**
282
	 * Can the current user edit the given member?
283
	 *
284
	 * @return true if this member can be edited, false otherwise
285
	 */
286
	function canEdit($member = null) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
287
		if(!$member) $member = Member::currentUser();
288
		
289
		if($this->owner->ID == Member::currentUserID()) return true;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return true; (boolean) is incompatible with the return type documented by ForumRole::canEdit of type true.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
290
291
		if($member) return $member->can('AdminCMS');
292
293
		return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by ForumRole::canEdit of type true.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
294
	}
295
296
297
	/**
298
	 * Used in preference to the Nickname field on templates
299
	 *
300
	 * Provides a default for the nickname field (first name, or "Anonymous
301
	 * User" if that's not set)
302
	 */
303
	function Nickname() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
304
		if($this->owner->Nickname) return $this->owner->Nickname;
305
		elseif($this->owner->FirstNamePublic && $this->owner->FirstName) return $this->owner->FirstName;
306
		else return _t('ForumRole.ANONYMOUS','Anonymous user');
307
	}
308
	
309
	/** 
310
	 * Return the url of the avatar or gravatar of the selected user.
311
	 * Checks to see if the current user has an avatar, if they do use it
312
	 * otherwise query gravatar.com
313
	 * 
314
	 * @return String
315
	 */
316
	function getFormattedAvatar() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
317
		$default = "forum/images/forummember_holder.gif";
318
		$currentTheme = Config::inst()->get('SSViewer', 'theme');
319
320
		if(file_exists('themes/' . $currentTheme . '_forum/images/forummember_holder.gif')) {
321
			$default = 'themes/' . $currentTheme . '_forum/images/forummember_holder.gif';
322
		}
323
		// if they have uploaded an image
324
		if($this->owner->AvatarID) {
325
			$avatar = Image::get()->byID($this->owner->AvatarID);
326
			if(!$avatar) return $default;
327
			
328
			$resizedAvatar = $avatar->SetWidth(80);
329
			if(!$resizedAvatar) return $default;
330
			
331
			return $resizedAvatar->URL;
332
		}
333
334
		//If Gravatar is enabled, allow the selection of the type of default Gravatar.
335
		if($holder = ForumHolder::get()->filter('AllowGravatars',1)->first()) {
336
			// If the GravatarType is one of the special types, then set it otherwise use the 
337
			//default image from above forummember_holder.gif
338
			if($holder->GravatarType){
339
 				$default = $holder->GravatarType;
340
 			} else {
341
 				// we need to get the absolute path for the default forum image
342
 				return $default;
343
 			}
344
			// ok. no image but can we find a gravatar. Will return the default image as defined above if not.
345
			return "http://www.gravatar.com/avatar/".md5($this->owner->Email)."?default=".urlencode($default)."&amp;size=80";
346
		}
347
348
		return $default;
349
	}
350
351
	/**
352
	 * Conditionally includes admin email address (hence we can't simply generate this 
353
	 * message in templates). We don't need to spam protect the email address as 
354
	 * the note only shows to logged-in users.
355
	 * 
356
	 * @return String
357
	 */
358
	function ForumSuspensionMessage() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
359
		$msg = _t('ForumRole.SUSPENSIONNOTE', 'This forum account has been suspended.');
360
		$adminEmail = Config::inst()->get('Email', 'admin_email');
361
362
		if($adminEmail) {
363
			$msg .= ' ' . sprintf(
364
				_t('ForumRole.SUSPENSIONEMAILNOTE', 'Please contact %s to resolve this issue.'),
365
				$adminEmail
366
			);
367
		}
368
		return $msg;
369
	}
370
}
371
372
373
374
/**
375
 * ForumRole_Validator
376
 *
377
 * This class is used to validate the new fields added by the
378
 * {@link ForumRole} decorator in the CMS backend.
379
 */
380
class ForumRole_Validator extends Extension {
381
382
	/**
383
	 * Client-side validation code
384
	 *
385
	 * @param string $js The javascript validation code
386
	 * @return string Returns the needed javascript code for client-side
387
	 *                validation.
388
	 */
389
	function updateJavascript(&$js, &$form) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
390
391
		$formID = $form->FormName();
392
		$passwordFieldName = $form->dataFieldByName('Password')->id();
393
394
		$passwordConfirmField = $form->dataFieldByName('ConfirmPassword');
395
		if(!$passwordConfirmField) return;
396
397
		$passwordConfirmFieldName = $passwordConfirmField->id();
398
399
		$passwordcheck = <<<JS
400
Behaviour.register({
401
	"#$formID": {
402
		validatePasswordConfirmation: function() {
403
			var passEl = _CURRENT_FORM.elements['Password'];
404
			var confEl = _CURRENT_FORM.elements['ConfirmPassword'];
405
406
			if(passEl.value == confEl.value) {
407
			  clearErrorMessage(confEl.parentNode);
408
				return true;
409
			} else {
410
				validationError(confEl, "Passwords don't match.", "error");
411
				return false;
412
			}
413
		},
414
		initialize: function() {
415
			var passEl = $('$passwordFieldName');
416
			var confEl = $('$passwordConfirmFieldName');
417
418
			confEl.value = passEl.value;
419
		}
420
	}
421
});
422
JS;
423
		Requirements::customScript($passwordcheck,
424
															 'func_validatePasswordConfirmation');
425
426
		$js .= "\$('$formID').validatePasswordConfirmation();";
427
		return $js;
428
	}
429
}
430