mirror of
https://github.com/processwire/processwire.git
synced 2025-08-16 19:54:24 +02:00
Upgrade FieldtypeComments to support custom fields via new meta functions. Also upgrade ProcessCommentsManager and InputfieldCommentsAdmin for support. InputfieldCommentsAdmin was also upgraded with an option to link to the comments manager rather than making comments editable in the page editor (see "Input" tab for that config option).
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
*
|
*
|
||||||
* Class that contains an individual comment.
|
* Class that contains an individual comment.
|
||||||
*
|
*
|
||||||
* ProcessWire 3.x, Copyright 2020 by Ryan Cramer
|
* ProcessWire 3.x, Copyright 2022 by Ryan Cramer
|
||||||
* https://processwire.com
|
* https://processwire.com
|
||||||
*
|
*
|
||||||
* @property int $id
|
* @property int $id
|
||||||
@@ -195,12 +195,23 @@ class Comment extends WireData {
|
|||||||
$this->set('website', '');
|
$this->set('website', '');
|
||||||
$this->set('ip', '');
|
$this->set('ip', '');
|
||||||
$this->set('user_agent', '');
|
$this->set('user_agent', '');
|
||||||
$this->set('created_users_id', $this->config->guestUserPageID);
|
$this->set('created_users_id', 40);
|
||||||
$this->set('code', ''); // approval code
|
$this->set('code', ''); // approval code
|
||||||
$this->set('subcode', ''); // subscriber code (for later user modifications to comment)
|
$this->set('subcode', ''); // subscriber code (for later user modifications to comment)
|
||||||
$this->set('upvotes', 0);
|
$this->set('upvotes', 0);
|
||||||
$this->set('downvotes', 0);
|
$this->set('downvotes', 0);
|
||||||
$this->set('stars', 0);
|
$this->set('stars', 0);
|
||||||
|
$this->set('meta', array());
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wired to API
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function wired() {
|
||||||
|
$this->set('created_users_id', $this->wire()->config->guestUserPageID);
|
||||||
|
parent::wired();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -213,8 +224,7 @@ class Comment extends WireData {
|
|||||||
public function get($key) {
|
public function get($key) {
|
||||||
|
|
||||||
if($key === 'user' || $key === 'createdUser') {
|
if($key === 'user' || $key === 'createdUser') {
|
||||||
if(!$this->created_users_id) return $this->users->get($this->config->guestUserPageID);
|
return $this->wire()->users->get($this->created_users_id);
|
||||||
return $this->users->get($this->created_users_id);
|
|
||||||
|
|
||||||
} else if($key === 'gravatar') {
|
} else if($key === 'gravatar') {
|
||||||
return $this->gravatar();
|
return $this->gravatar();
|
||||||
@@ -243,7 +253,7 @@ class Comment extends WireData {
|
|||||||
} else if($key === 'editUrl' || $key == 'editURL') {
|
} else if($key === 'editUrl' || $key == 'editURL') {
|
||||||
return $this->editUrl();
|
return $this->editUrl();
|
||||||
|
|
||||||
} else if($key === 'prevStatus') {
|
} else if($key === 'prevStatus' || $key === 'statusPrevious') {
|
||||||
return $this->prevStatus;
|
return $this->prevStatus;
|
||||||
|
|
||||||
} else if($key === 'textFormatted') {
|
} else if($key === 'textFormatted') {
|
||||||
@@ -329,9 +339,11 @@ class Comment extends WireData {
|
|||||||
if(is_array($textformatters) && count($textformatters)) {
|
if(is_array($textformatters) && count($textformatters)) {
|
||||||
// output formatting with specified textformatters (@todo)
|
// output formatting with specified textformatters (@todo)
|
||||||
// NOT CURRENTLY ACTIVE
|
// NOT CURRENTLY ACTIVE
|
||||||
|
$modules = $this->wire()->modules;
|
||||||
$value = strip_tags($value);
|
$value = strip_tags($value);
|
||||||
foreach($textformatters as $name) {
|
foreach($textformatters as $name) {
|
||||||
if(!$textformatter = $this->wire('modules')->get($name)) continue;
|
/** @var Textformatter $textformatter */
|
||||||
|
if(!$textformatter = $modules->get($name)) continue;
|
||||||
$textformatter->formatValue($this->page, $this->field, $value);
|
$textformatter->formatValue($this->page, $this->field, $value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -389,21 +401,23 @@ class Comment extends WireData {
|
|||||||
} else if($key === 'numChildren') {
|
} else if($key === 'numChildren') {
|
||||||
$this->numChildren = (int) $value;
|
$this->numChildren = (int) $value;
|
||||||
return $this;
|
return $this;
|
||||||
|
} else if($key === 'meta') {
|
||||||
|
if(!is_array($value)) return $this; // array required for meta
|
||||||
}
|
}
|
||||||
|
|
||||||
// save the state so that modules can identify when a comment that was identified as spam
|
// save the state so that modules can identify when a comment that was identified as spam
|
||||||
// is then set to not-spam, or when a misidentified 'approved' comment is actually spam
|
// is then set to not-spam, or when a misidentified 'approved' comment is actually spam
|
||||||
if($key == 'status' && $this->loaded) {
|
if($key === 'status' && $this->loaded) {
|
||||||
$this->prevStatus = $this->status;
|
$this->prevStatus = $this->status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($key == 'stars') {
|
if($key === 'stars') {
|
||||||
$value = (int) $value;
|
$value = (int) $value;
|
||||||
if($value < 1) $value = 0;
|
if($value < 1) $value = 0;
|
||||||
if($value > 5) $value = 5;
|
if($value > 5) $value = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($key == 'parent_id' && parent::get('parent_id') != $value) {
|
if($key === 'parent_id' && parent::get('parent_id') != $value) {
|
||||||
// reset a cached parent value, if present
|
// reset a cached parent value, if present
|
||||||
$this->_parent = null;
|
$this->_parent = null;
|
||||||
}
|
}
|
||||||
@@ -431,7 +445,7 @@ class Comment extends WireData {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function __toString() {
|
public function __toString() {
|
||||||
return "{$this->id}";
|
return "$this->id";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -456,7 +470,7 @@ class Comment extends WireData {
|
|||||||
if(!in_array($rating, array('g', 'pg', 'r', 'x'), true)) $rating = 'g';
|
if(!in_array($rating, array('g', 'pg', 'r', 'x'), true)) $rating = 'g';
|
||||||
if(empty($imageset)) $imageset = 'mm';
|
if(empty($imageset)) $imageset = 'mm';
|
||||||
$size = (int) $size;
|
$size = (int) $size;
|
||||||
$http = wire('config')->https ? 'https' : 'http';
|
$http = wire()->config->https ? 'https' : 'http';
|
||||||
$url = "$http://www.gravatar.com/avatar/" .
|
$url = "$http://www.gravatar.com/avatar/" .
|
||||||
md5(strtolower(trim($email))) .
|
md5(strtolower(trim($email))) .
|
||||||
"?s=$size" .
|
"?s=$size" .
|
||||||
@@ -763,7 +777,8 @@ class Comment extends WireData {
|
|||||||
if($this->page && $this->page->id) {
|
if($this->page && $this->page->id) {
|
||||||
$url = $http ? $this->page->httpUrl() : $this->page->url;
|
$url = $http ? $this->page->httpUrl() : $this->page->url;
|
||||||
} else {
|
} else {
|
||||||
$url = $http ? $this->wire('config')->urls->httpRoot : $this->wire('config')->urls->root;
|
$config = $this->wire()->config;
|
||||||
|
$url = $http ? $config->urls->httpRoot : $config->urls->root;
|
||||||
}
|
}
|
||||||
return $url . "#Comment$this->id";
|
return $url . "#Comment$this->id";
|
||||||
}
|
}
|
||||||
@@ -789,6 +804,105 @@ class Comment extends WireData {
|
|||||||
if(!$this->field) return '';
|
if(!$this->field) return '';
|
||||||
return $this->page->editUrl() . "?field={$this->field->name}#CommentsAdminItem$this->id";
|
return $this->page->editUrl() . "?field={$this->field->name}#CommentsAdminItem$this->id";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set meta data (custom fields for comments)
|
||||||
|
*
|
||||||
|
* To set multiple properties at once specify an associative array for $key and omit $value.
|
||||||
|
*
|
||||||
|
* @param string|array $key Property name to set or assoc array of them
|
||||||
|
* @param null|string|array|int|float|mixed $value Value to set for $key or omit of you used an array.
|
||||||
|
* @return self
|
||||||
|
* @since 3.0.203
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function setMeta($key, $value = null) {
|
||||||
|
$meta = parent::get('meta');
|
||||||
|
$changed = false;
|
||||||
|
|
||||||
|
if(is_array($key)) {
|
||||||
|
// set multiple properties
|
||||||
|
$changed = $meta != $key;
|
||||||
|
if($changed) $meta = count($meta) ? array_merge($meta, $key) : $key;
|
||||||
|
|
||||||
|
} else if($value === null) {
|
||||||
|
if($key === '*') {
|
||||||
|
// remove all
|
||||||
|
$changed = count($meta) > 0;
|
||||||
|
$meta = array();
|
||||||
|
} else if(isset($meta[$key])) {
|
||||||
|
// remove property
|
||||||
|
unset($meta[$key]);
|
||||||
|
$changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// set property
|
||||||
|
$changed = !isset($meta[$key]) || $meta[$key] !== $value;
|
||||||
|
$meta[$key] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::set('meta', $meta);
|
||||||
|
if($changed) $this->trackChange('meta');
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get meta data property value (custom fields for comments)
|
||||||
|
*
|
||||||
|
* Note: values returned are exactly as they were set and do not go through any runtime
|
||||||
|
* formatting for HTML entities or anything like that. Be sure to provide your own formatting
|
||||||
|
* where necessary.
|
||||||
|
*
|
||||||
|
* @param null|string $key Name of property to get
|
||||||
|
* @return string|array|int|float|mixed|null Returns value or null if not found
|
||||||
|
* @since 3.0.203
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function getMeta($key = null) {
|
||||||
|
$meta = parent::get('meta');
|
||||||
|
if(empty($key)) return $meta;
|
||||||
|
if(isset($meta[$key])) return $meta[$key];
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove given meta data property or '*' to remove all
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @return self
|
||||||
|
* @since 3.0.203
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function removeMeta($key) {
|
||||||
|
return $this->setMeta($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get or set meta data property
|
||||||
|
*
|
||||||
|
* @param string|array $key Property to get/set or omit to get all.
|
||||||
|
* @param mixed|null $value Value to set for given property ($key) or omit if getting.
|
||||||
|
* @return array|string|int|mixed Returns value for $key or null if it does not exist. Returns array when getting all.
|
||||||
|
* @since 3.0.203
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function meta($key = null, $value = null) {
|
||||||
|
if($key === null) {
|
||||||
|
// get all
|
||||||
|
$value = $this->getMeta();
|
||||||
|
} else if($value === null) {
|
||||||
|
// get one property
|
||||||
|
if(!is_string($key)) throw new WireException('Expected string for $key to Comment::meta()');
|
||||||
|
$value = $this->getMeta($key);
|
||||||
|
} else {
|
||||||
|
// set one property
|
||||||
|
$this->setMeta($key, $value);
|
||||||
|
}
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
* /wire/core/Fieldtype.php
|
* /wire/core/Fieldtype.php
|
||||||
* /wire/core/FieldtypeMulti.php
|
* /wire/core/FieldtypeMulti.php
|
||||||
*
|
*
|
||||||
* ProcessWire 3.x, Copyright 2020 by Ryan Cramer
|
* ProcessWire 3.x, Copyright 2022 by Ryan Cramer
|
||||||
* https://processwire.com
|
* https://processwire.com
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -75,16 +75,17 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
public static function getModuleInfo() {
|
public static function getModuleInfo() {
|
||||||
return array(
|
return array(
|
||||||
'title' => __('Comments', __FILE__),
|
'title' => __('Comments', __FILE__),
|
||||||
'version' => 109,
|
'version' => 110,
|
||||||
'summary' => __('Field that stores user posted comments for a single Page', __FILE__),
|
'summary' => __('Field that stores user posted comments for a single Page', __FILE__),
|
||||||
'installs' => array('InputfieldCommentsAdmin'),
|
'installs' => array('InputfieldCommentsAdmin'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function wired() {
|
public function wired() {
|
||||||
if($this->wire('config')->ajax) {
|
if($this->wire()->config->ajax) {
|
||||||
$this->addHookBefore('Page::render', $this, 'checkVoteAction');
|
$this->addHookBefore('Page::render', $this, 'checkVoteAction');
|
||||||
}
|
}
|
||||||
|
parent::wired();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBlankValue(Page $page, Field $field) {
|
public function getBlankValue(Page $page, Field $field) {
|
||||||
@@ -97,7 +98,8 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
|
|
||||||
public function sanitizeValue(Page $page, Field $field, $value) {
|
public function sanitizeValue(Page $page, Field $field, $value) {
|
||||||
if($value instanceof CommentArray) return $value;
|
if($value instanceof CommentArray) return $value;
|
||||||
$commentArray = $this->wire('pages')->get($field->name);
|
/** @var CommentArray $commentArray */
|
||||||
|
$commentArray = $this->wire()->pages->get($field->name);
|
||||||
if(!$value) return $commentArray;
|
if(!$value) return $commentArray;
|
||||||
if($value instanceof Comment) return $commentArray->add($value);
|
if($value instanceof Comment) return $commentArray->add($value);
|
||||||
if(!is_array($value)) $value = array($value);
|
if(!is_array($value)) $value = array($value);
|
||||||
@@ -107,7 +109,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
|
|
||||||
public function getInputfield(Page $page, Field $field) {
|
public function getInputfield(Page $page, Field $field) {
|
||||||
/** @var InputfieldCommentsAdmin $inputfield */
|
/** @var InputfieldCommentsAdmin $inputfield */
|
||||||
$inputfield = $this->modules->get('InputfieldCommentsAdmin');
|
$inputfield = $this->wire()->modules->get('InputfieldCommentsAdmin');
|
||||||
if(!$inputfield) return null;
|
if(!$inputfield) return null;
|
||||||
$inputfield->set('class', $this->className());
|
$inputfield->set('class', $this->className());
|
||||||
return $inputfield;
|
return $inputfield;
|
||||||
@@ -164,15 +166,9 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
|
|
||||||
// don't load non-approved comments if the user can't edit them
|
// don't load non-approved comments if the user can't edit them
|
||||||
if(!$editable && $item['status'] < Comment::statusApproved) continue;
|
if(!$editable && $item['status'] < Comment::statusApproved) continue;
|
||||||
|
|
||||||
$comment = $this->wire(new Comment());
|
/** @var Comment $comment */
|
||||||
$comment->setPage($page);
|
$comment = $this->makeComment($page, $field, $item);
|
||||||
$comment->setField($field);
|
|
||||||
foreach($item as $key => $val) {
|
|
||||||
if($key == 'data') $key = 'text';
|
|
||||||
$comment->set($key, $val);
|
|
||||||
}
|
|
||||||
$comment->resetTrackChanges(true);
|
|
||||||
$commentArray->add($comment);
|
$commentArray->add($comment);
|
||||||
$comment->setIsLoaded(true);
|
$comment->setIsLoaded(true);
|
||||||
}
|
}
|
||||||
@@ -238,6 +234,9 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
if($schemaVersion > 5) {
|
if($schemaVersion > 5) {
|
||||||
$a['stars'] = ($comment->stars >= 1 && $comment->stars <= 5 ? (int) $comment->stars : null);
|
$a['stars'] = ($comment->stars >= 1 && $comment->stars <= 5 ? (int) $comment->stars : null);
|
||||||
}
|
}
|
||||||
|
if($schemaVersion > 7) {
|
||||||
|
$a['meta'] = json_encode($comment->getMeta());
|
||||||
|
}
|
||||||
|
|
||||||
$sleepValue[] = $a;
|
$sleepValue[] = $a;
|
||||||
|
|
||||||
@@ -280,7 +279,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
|
|
||||||
if($field->get('useAkismet') && $comment->ip && $comment->user_agent && ($submitHam || $submitSpam)) {
|
if($field->get('useAkismet') && $comment->ip && $comment->user_agent && ($submitHam || $submitSpam)) {
|
||||||
/** @var CommentFilterAkismet $akismet */
|
/** @var CommentFilterAkismet $akismet */
|
||||||
$akismet = $this->modules->get("CommentFilterAkismet");
|
$akismet = $this->wire()->modules->get('CommentFilterAkismet');
|
||||||
$akismet->setComment($comment);
|
$akismet->setComment($comment);
|
||||||
if($submitHam) $akismet->submitHam();
|
if($submitHam) $akismet->submitHam();
|
||||||
else if($submitSpam) $akismet->submitSpam();
|
else if($submitSpam) $akismet->submitSpam();
|
||||||
@@ -331,7 +330,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
|
|
||||||
if($field->get('useAkismet')) {
|
if($field->get('useAkismet')) {
|
||||||
/** @var CommentFilterAkismet $akismet */
|
/** @var CommentFilterAkismet $akismet */
|
||||||
$akismet = $this->modules->get('CommentFilterAkismet');
|
$akismet = $this->wire()->modules->get('CommentFilterAkismet');
|
||||||
$akismet->setComment($comment);
|
$akismet->setComment($comment);
|
||||||
$akismet->checkSpam(); // automatically sets status if spam
|
$akismet->checkSpam(); // automatically sets status if spam
|
||||||
} else {
|
} else {
|
||||||
@@ -344,7 +343,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
$comment->approvalNote = 'New comment approved / moderation is off';
|
$comment->approvalNote = 'New comment approved / moderation is off';
|
||||||
|
|
||||||
} else if($field->get('moderate') == self::moderateNew && $comment->email) {
|
} else if($field->get('moderate') == self::moderateNew && $comment->email) {
|
||||||
$database = $this->wire('database');
|
$database = $this->wire()->database;
|
||||||
$table = $database->escapeTable($field->table);
|
$table = $database->escapeTable($field->table);
|
||||||
$query = $database->prepare("SELECT count(*) FROM `$table` WHERE status=:status AND email=:email");
|
$query = $database->prepare("SELECT count(*) FROM `$table` WHERE status=:status AND email=:email");
|
||||||
$query->bindValue(":status", Comment::statusApproved, \PDO::PARAM_INT);
|
$query->bindValue(":status", Comment::statusApproved, \PDO::PARAM_INT);
|
||||||
@@ -353,7 +352,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
$numApproved = (int) $query->fetchColumn();
|
$numApproved = (int) $query->fetchColumn();
|
||||||
|
|
||||||
if($numApproved > 0) {
|
if($numApproved > 0) {
|
||||||
$cite = $this->wire('sanitizer')->text($comment->cite);
|
$cite = $this->wire()->sanitizer->text($comment->cite);
|
||||||
$comment->status = Comment::statusApproved;
|
$comment->status = Comment::statusApproved;
|
||||||
$comment->approvalNote = "New comment auto-approved because user '$cite' has other approved comments";
|
$comment->approvalNote = "New comment auto-approved because user '$cite' has other approved comments";
|
||||||
}
|
}
|
||||||
@@ -369,7 +368,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
*/
|
*/
|
||||||
protected function commentMaintenance(Field $field) {
|
protected function commentMaintenance(Field $field) {
|
||||||
|
|
||||||
$database = $this->wire('database');
|
$database = $this->wire()->database;
|
||||||
$table = $database->escapeTable($field->table);
|
$table = $database->escapeTable($field->table);
|
||||||
|
|
||||||
// delete old spam
|
// delete old spam
|
||||||
@@ -414,51 +413,59 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
$downvoteSchema = "int unsigned NOT NULL default 0";
|
$downvoteSchema = "int unsigned NOT NULL default 0";
|
||||||
$starsSchema = "tinyint unsigned default NULL";
|
$starsSchema = "tinyint unsigned default NULL";
|
||||||
$ipSchema = "varchar(45) NOT NULL default ''";
|
$ipSchema = "varchar(45) NOT NULL default ''";
|
||||||
|
$metaSchema = "text DEFAULT NULL";
|
||||||
|
$table = $field->getTable();
|
||||||
|
|
||||||
$schemaVersion = (int) $field->get('schemaVersion');
|
$schemaVersion = (int) $field->get('schemaVersion');
|
||||||
$updateSchema = true;
|
$updateSchema = true;
|
||||||
|
|
||||||
if(!$schemaVersion) {
|
if(!$schemaVersion) {
|
||||||
// add website field for PW 2.3+
|
// add website field for PW 2.3+
|
||||||
$table = $database->escapeTable($field->getTable());
|
|
||||||
try {
|
try {
|
||||||
$database->query("ALTER TABLE `$table` ADD website $websiteSchema");
|
if(!$database->columnExists($table, 'website')) {
|
||||||
|
$database->query("ALTER TABLE `$table` ADD website $websiteSchema");
|
||||||
|
}
|
||||||
$schemaVersion = 1;
|
$schemaVersion = 1;
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
$updateSchema = false;
|
$updateSchema = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($schemaVersion < 2) {
|
if($schemaVersion < 2 && $updateSchema) {
|
||||||
// add parent_id and flags columns
|
// add parent_id and flags columns
|
||||||
$table = $database->escapeTable($field->getTable());
|
|
||||||
try {
|
try {
|
||||||
$database->query("ALTER TABLE `$table` ADD parent_id $parentSchema");
|
if(!$database->columnExists($table, 'parent_id')) {
|
||||||
$database->query("ALTER TABLE `$table` ADD flags $flagSchema");
|
$database->query("ALTER TABLE `$table` ADD parent_id $parentSchema");
|
||||||
|
}
|
||||||
|
if(!$database->columnExists($table, 'flags')) {
|
||||||
|
$database->query("ALTER TABLE `$table` ADD flags $flagSchema");
|
||||||
|
}
|
||||||
$schemaVersion = 2;
|
$schemaVersion = 2;
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
$updateSchema = false;
|
$updateSchema = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($schemaVersion < 3) {
|
if($schemaVersion < 3 && $updateSchema) {
|
||||||
// add code column (admin code)
|
// add code column (admin code)
|
||||||
$table = $database->escapeTable($field->getTable());
|
|
||||||
try {
|
try {
|
||||||
$database->query("ALTER TABLE `$table` ADD `code` $codeSchema");
|
if(!$database->columnExists($table, 'code')) {
|
||||||
$database->query("ALTER TABLE `$table` ADD $codeIndexSchema");
|
$database->query("ALTER TABLE `$table` ADD `code` $codeSchema");
|
||||||
|
$database->query("ALTER TABLE `$table` ADD $codeIndexSchema");
|
||||||
|
}
|
||||||
$schemaVersion = 3;
|
$schemaVersion = 3;
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
$updateSchema = false;
|
$updateSchema = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($schemaVersion < 4) {
|
if($schemaVersion < 4 && $updateSchema) {
|
||||||
// add subcode column (subscriber code)
|
// add subcode column (subscriber code)
|
||||||
$table = $database->escapeTable($field->getTable());
|
|
||||||
try {
|
try {
|
||||||
$database->query("ALTER TABLE `$table` ADD `subcode` $subcodeSchema");
|
if(!$database->columnExists($table, 'subcode')) {
|
||||||
$database->query("ALTER TABLE `$table` ADD $subcodeIndexSchema");
|
$database->query("ALTER TABLE `$table` ADD `subcode` $subcodeSchema");
|
||||||
|
$database->query("ALTER TABLE `$table` ADD $subcodeIndexSchema");
|
||||||
|
}
|
||||||
$schemaVersion = 4;
|
$schemaVersion = 4;
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
$updateSchema = false;
|
$updateSchema = false;
|
||||||
@@ -467,20 +474,21 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
|
|
||||||
if($schemaVersion < 5 && $updateSchema) {
|
if($schemaVersion < 5 && $updateSchema) {
|
||||||
// add upvote/downvote columns
|
// add upvote/downvote columns
|
||||||
$table = $database->escapeTable($field->getTable());
|
|
||||||
$parentSchema = parent::getDatabaseSchema($field);
|
$parentSchema = parent::getDatabaseSchema($field);
|
||||||
try {
|
try {
|
||||||
$sql = "
|
if(!$database->tableExists("{$table}_votes")) {
|
||||||
CREATE TABLE `{$table}_votes` (
|
$sql = "
|
||||||
`comment_id` int unsigned NOT NULL,
|
CREATE TABLE `{$table}_votes` (
|
||||||
`vote` tinyint NOT NULL,
|
`comment_id` int unsigned NOT NULL,
|
||||||
`created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`vote` tinyint NOT NULL,
|
||||||
`ip` $ipSchema,
|
`created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`user_id` int unsigned NOT NULL default 0,
|
`ip` $ipSchema,
|
||||||
PRIMARY KEY (`comment_id`, `ip`, `vote`),
|
`user_id` int unsigned NOT NULL default 0,
|
||||||
INDEX `created` (`created`)
|
PRIMARY KEY (`comment_id`, `ip`, `vote`),
|
||||||
) " . $parentSchema['xtra']['append']; // engine and charset
|
INDEX `created` (`created`)
|
||||||
$database->exec($sql);
|
) " . $parentSchema['xtra']['append']; // engine and charset
|
||||||
|
$database->exec($sql);
|
||||||
|
}
|
||||||
$createdVotesTable = true;
|
$createdVotesTable = true;
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
$createdVotesTable = $e->getCode() == '42S01'; // 42S01=table already exists (which we consider success too)
|
$createdVotesTable = $e->getCode() == '42S01'; // 42S01=table already exists (which we consider success too)
|
||||||
@@ -490,12 +498,12 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if($createdVotesTable) try {
|
if($createdVotesTable) try {
|
||||||
$isUpvotes = $database->prepare("SHOW columns FROM `$table` LIKE 'upvotes'");
|
if(!$database->columnExists($table, 'upvotes')) {
|
||||||
$isUpvotes->execute();
|
$database->query("ALTER TABLE `$table` ADD `upvotes` $upvoteSchema");
|
||||||
if(!$isUpvotes->rowCount()) $database->query("ALTER TABLE `$table` ADD `upvotes` $upvoteSchema");
|
}
|
||||||
$isDownvotes = $database->prepare("SHOW columns FROM `$table` LIKE 'downvotes'");
|
if(!$database->columnExists($table, 'downvotes')) {
|
||||||
$isDownvotes->execute();
|
$database->query("ALTER TABLE `$table` ADD `downvotes` $downvoteSchema");
|
||||||
if(!$isDownvotes->rowCount()) $database->query("ALTER TABLE `$table` ADD `downvotes` $downvoteSchema");
|
}
|
||||||
$schemaVersion = 5;
|
$schemaVersion = 5;
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
$this->error($e->getMessage(), Notice::log);
|
$this->error($e->getMessage(), Notice::log);
|
||||||
@@ -504,28 +512,37 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if($schemaVersion < 6 && $updateSchema) {
|
if($schemaVersion < 6 && $updateSchema) {
|
||||||
$table = $database->escapeTable($field->getTable());
|
|
||||||
try {
|
try {
|
||||||
$database->query("ALTER TABLE `$table` ADD `stars` $starsSchema");
|
if(!$database->columnExists($table, 'stars')) {
|
||||||
|
$database->query("ALTER TABLE `$table` ADD `stars` $starsSchema");
|
||||||
|
}
|
||||||
$schemaVersion = 6;
|
$schemaVersion = 6;
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
if($e->getCode() == '42S21') {
|
$updateSchema = false;
|
||||||
// column already exists
|
|
||||||
$schemaVersion = 6;
|
|
||||||
} else {
|
|
||||||
// $updateSchema = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($schemaVersion < 7 && $updateSchema) {
|
if($schemaVersion < 7 && $updateSchema) {
|
||||||
$table = $database->escapeTable($field->getTable());
|
|
||||||
try {
|
try {
|
||||||
$database->query("ALTER TABLE `$table` MODIFY `ip` $ipSchema");
|
$database->query("ALTER TABLE `$table` MODIFY `ip` $ipSchema");
|
||||||
$database->query("ALTER TABLE `{$table}_votes` MODIFY `ip` $ipSchema");
|
if($database->tableExists("{$table}_votes")) {
|
||||||
|
$database->query("ALTER TABLE `{$table}_votes` MODIFY `ip` $ipSchema");
|
||||||
|
}
|
||||||
$schemaVersion = 7;
|
$schemaVersion = 7;
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
$this->error($e->getMessage(), Notice::debug);
|
$this->error($e->getMessage(), Notice::debug);
|
||||||
|
$updateSchema = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($schemaVersion < 8 && $updateSchema) {
|
||||||
|
try {
|
||||||
|
if(!$database->columnExists($table, 'meta')) {
|
||||||
|
$database->query("ALTER TABLE `$table` ADD `meta` $metaSchema");
|
||||||
|
}
|
||||||
|
$schemaVersion = 8;
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
$this->error($e->getMessage(), Notice::debug);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -570,6 +587,9 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
if($schemaVersion > 5) {
|
if($schemaVersion > 5) {
|
||||||
$schema['stars'] = $starsSchema;
|
$schema['stars'] = $starsSchema;
|
||||||
}
|
}
|
||||||
|
if($schemaVersion > 7) {
|
||||||
|
$schema['meta'] = $metaSchema;
|
||||||
|
}
|
||||||
|
|
||||||
$schema['keys']['primary'] = "PRIMARY KEY (`id`)";
|
$schema['keys']['primary'] = "PRIMARY KEY (`id`)";
|
||||||
$schema['keys']['pages_id_sort'] = "KEY `pages_id_sort` (`pages_id`, `sort`)";
|
$schema['keys']['pages_id_sort'] = "KEY `pages_id_sort` (`pages_id`, `sort`)";
|
||||||
@@ -596,7 +616,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
|
|
||||||
/** @var CommentArray $allItems */
|
/** @var CommentArray $allItems */
|
||||||
$allItems = $page->get($field->name);
|
$allItems = $page->get($field->name);
|
||||||
$database = $this->wire('database');
|
$database = $this->wire()->database;
|
||||||
$table = $database->escapeTable($field->table);
|
$table = $database->escapeTable($field->table);
|
||||||
|
|
||||||
if(!$allItems) return false;
|
if(!$allItems) return false;
|
||||||
@@ -692,20 +712,25 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
*
|
*
|
||||||
* @param Field $field
|
* @param Field $field
|
||||||
* @return InputfieldWrapper
|
* @return InputfieldWrapper
|
||||||
|
* @todo move to separate config file
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function ___getConfigInputfields(Field $field) {
|
public function ___getConfigInputfields(Field $field) {
|
||||||
|
|
||||||
|
$modules = $this->wire()->modules;
|
||||||
|
|
||||||
$inputfields = parent::___getConfigInputfields($field);
|
$inputfields = parent::___getConfigInputfields($field);
|
||||||
$disabledLabel = $this->_('Disabled');
|
$disabledLabel = $this->_('Disabled');
|
||||||
|
|
||||||
$fieldset = $this->wire('modules')->get('InputfieldFieldset');
|
/** @var InputfieldFieldset $fieldset */
|
||||||
|
$fieldset = $modules->get('InputfieldFieldset');
|
||||||
$fieldset->label = $this->_('Behavior');
|
$fieldset->label = $this->_('Behavior');
|
||||||
$fieldset->icon = 'comment-o';
|
$fieldset->icon = 'comment-o';
|
||||||
$inputfields->add($fieldset);
|
$inputfields->add($fieldset);
|
||||||
|
|
||||||
|
/** @var InputfieldRadios $f */
|
||||||
|
$f = $modules->get('InputfieldRadios');
|
||||||
$name = 'moderate';
|
$name = 'moderate';
|
||||||
$f = $this->wire('modules')->get('InputfieldRadios');
|
|
||||||
$f->attr('name', $name);
|
$f->attr('name', $name);
|
||||||
$f->addOption(self::moderateNone, $this->_('None - Comments posted immediately'));
|
$f->addOption(self::moderateNone, $this->_('None - Comments posted immediately'));
|
||||||
$f->addOption(self::moderateAll, $this->_('All - All comments must be approved by user with page edit access'));
|
$f->addOption(self::moderateAll, $this->_('All - All comments must be approved by user with page edit access'));
|
||||||
@@ -714,9 +739,10 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
$f->label = $this->_('Comment moderation');
|
$f->label = $this->_('Comment moderation');
|
||||||
$f->description = $this->_('This determines when a newly posted comment will appear on your site.');
|
$f->description = $this->_('This determines when a newly posted comment will appear on your site.');
|
||||||
$fieldset->append($f);
|
$fieldset->append($f);
|
||||||
|
|
||||||
|
/** @var InputfieldCheckbox $f */
|
||||||
|
$f = $modules->get('InputfieldCheckbox');
|
||||||
$name = 'redirectAfterPost';
|
$name = 'redirectAfterPost';
|
||||||
$f = $this->wire('modules')->get('InputfieldCheckbox');
|
|
||||||
$f->attr('name', $name);
|
$f->attr('name', $name);
|
||||||
$f->attr('value', 1);
|
$f->attr('value', 1);
|
||||||
$f->attr('checked', $field->$name ? 'checked' : '');
|
$f->attr('checked', $field->$name ? 'checked' : '');
|
||||||
@@ -725,8 +751,9 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
$f->columnWidth = 50;
|
$f->columnWidth = 50;
|
||||||
$fieldset->append($f);
|
$fieldset->append($f);
|
||||||
|
|
||||||
|
/** @var InputfieldCheckbox $f */
|
||||||
|
$f = $modules->get('InputfieldCheckbox');
|
||||||
$name = 'quietSave';
|
$name = 'quietSave';
|
||||||
$f = $this->wire('modules')->get('InputfieldCheckbox');
|
|
||||||
$f->attr('name', $name);
|
$f->attr('name', $name);
|
||||||
$f->attr('value', 1);
|
$f->attr('value', 1);
|
||||||
$f->attr('checked', $field->$name ? 'checked' : '');
|
$f->attr('checked', $field->$name ? 'checked' : '');
|
||||||
@@ -749,14 +776,16 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// ----------------------------
|
// ----------------------------
|
||||||
|
|
||||||
$fieldset = $this->wire('modules')->get('InputfieldFieldset');
|
/** @var InputfieldFieldset $fieldset */
|
||||||
|
$fieldset = $modules->get('InputfieldFieldset');
|
||||||
$fieldset->label = $this->_('Notifications');
|
$fieldset->label = $this->_('Notifications');
|
||||||
$fieldset->icon = 'bell-o';
|
$fieldset->icon = 'bell-o';
|
||||||
$inputfields->add($fieldset);
|
$inputfields->add($fieldset);
|
||||||
|
|
||||||
|
/** @var InputfieldText $f */
|
||||||
|
$f = $modules->get('InputfieldText');
|
||||||
$name = 'notificationEmail';
|
$name = 'notificationEmail';
|
||||||
$f = $this->wire('modules')->get('InputfieldText');
|
|
||||||
$f->attr('name', $name);
|
$f->attr('name', $name);
|
||||||
$f->attr('value', $field->$name);
|
$f->attr('value', $field->$name);
|
||||||
$f->label = $this->_('Admin notification email');
|
$f->label = $this->_('Admin notification email');
|
||||||
@@ -769,18 +798,20 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
$this->_('3. Enter **123:email** to pull the email from an given page ID and field name, replacing "123" with the page ID and "email" with name of field containing email address.') . "\n" .
|
$this->_('3. Enter **123:email** to pull the email from an given page ID and field name, replacing "123" with the page ID and "email" with name of field containing email address.') . "\n" .
|
||||||
$this->_('4. Enter **/path/to/page:email** to pull the email from an given page path and field name, replacing "/path/to/page" with the page path and "email" with name of field containing email address.');
|
$this->_('4. Enter **/path/to/page:email** to pull the email from an given page path and field name, replacing "/path/to/page" with the page path and "email" with name of field containing email address.');
|
||||||
$fieldset->append($f);
|
$fieldset->append($f);
|
||||||
|
|
||||||
|
/** @var InputfieldEmail $f */
|
||||||
|
$f = $modules->get('InputfieldEmail');
|
||||||
$name = 'fromEmail';
|
$name = 'fromEmail';
|
||||||
$f = $this->wire('modules')->get('InputfieldEmail');
|
|
||||||
$f->attr('name', $name);
|
$f->attr('name', $name);
|
||||||
$f->attr('value', $field->$name);
|
$f->attr('value', $field->$name);
|
||||||
$f->label = $this->_('Notifications from email');
|
$f->label = $this->_('Notifications from email');
|
||||||
$f->description = $this->_('Optional e-mail address that notifications will appear from. Leave blank to use the default server email.');
|
$f->description = $this->_('Optional e-mail address that notifications will appear from. Leave blank to use the default server email.');
|
||||||
$f->columnWidth = 50;
|
$f->columnWidth = 50;
|
||||||
$fieldset->append($f);
|
$fieldset->append($f);
|
||||||
|
|
||||||
|
/** @var InputfieldCheckbox $f */
|
||||||
|
$f = $modules->get('InputfieldCheckbox');
|
||||||
$name = 'notifySpam';
|
$name = 'notifySpam';
|
||||||
$f = $this->wire('modules')->get('InputfieldCheckbox');
|
|
||||||
$f->attr('name', $name);
|
$f->attr('name', $name);
|
||||||
$f->attr('value', 1);
|
$f->attr('value', 1);
|
||||||
if($field->$name) $f->attr('checked', 'checked');
|
if($field->$name) $f->attr('checked', 'checked');
|
||||||
@@ -789,8 +820,9 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
$f->columnWidth = 50;
|
$f->columnWidth = 50;
|
||||||
$fieldset->append($f);
|
$fieldset->append($f);
|
||||||
|
|
||||||
|
/** @var InputfieldRadios $f */
|
||||||
|
$f = $modules->get('InputfieldRadios');
|
||||||
$name = 'useNotify';
|
$name = 'useNotify';
|
||||||
$f = $this->wire('modules')->get('InputfieldRadios');
|
|
||||||
$f->attr('name', $name);
|
$f->attr('name', $name);
|
||||||
$f->label = $this->_('Allow commenter e-mail notifications?');
|
$f->label = $this->_('Allow commenter e-mail notifications?');
|
||||||
$f->description = $this->_('This option enables anyone that posts a comment to receive email notifications of new comments.');
|
$f->description = $this->_('This option enables anyone that posts a comment to receive email notifications of new comments.');
|
||||||
@@ -800,9 +832,10 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
$f->attr('value', (int) $field->get('useNotify'));
|
$f->attr('value', (int) $field->get('useNotify'));
|
||||||
$f->columnWidth = 50;
|
$f->columnWidth = 50;
|
||||||
$fieldset->append($f);
|
$fieldset->append($f);
|
||||||
|
|
||||||
|
/** @var InputfieldCheckbox $f */
|
||||||
|
$f = $modules->get('InputfieldCheckbox');
|
||||||
$name = 'useNotifyText';
|
$name = 'useNotifyText';
|
||||||
$f = $this->wire('modules')->get('InputfieldCheckbox');
|
|
||||||
$f->attr('name', $name);
|
$f->attr('name', $name);
|
||||||
$f->attr('value', 1);
|
$f->attr('value', 1);
|
||||||
if($field->$name) $f->attr('checked', 'checked');
|
if($field->$name) $f->attr('checked', 'checked');
|
||||||
@@ -813,14 +846,16 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
$fieldset->append($f);
|
$fieldset->append($f);
|
||||||
|
|
||||||
// ---------------------------------------
|
// ---------------------------------------
|
||||||
|
|
||||||
$fieldset = $this->wire('modules')->get('InputfieldFieldset');
|
/** @var InputfieldFieldset $fieldset */
|
||||||
|
$fieldset = $modules->get('InputfieldFieldset');
|
||||||
$fieldset->label = $this->_('Spam');
|
$fieldset->label = $this->_('Spam');
|
||||||
$fieldset->icon = 'fire-extinguisher';
|
$fieldset->icon = 'fire-extinguisher';
|
||||||
$inputfields->add($fieldset);
|
$inputfields->add($fieldset);
|
||||||
|
|
||||||
|
/** @var InputfieldCheckbox $f */
|
||||||
|
$f = $modules->get('InputfieldCheckbox');
|
||||||
$name = 'useAkismet';
|
$name = 'useAkismet';
|
||||||
$f = $this->wire('modules')->get('InputfieldCheckbox');
|
|
||||||
$f->attr('name', $name);
|
$f->attr('name', $name);
|
||||||
$f->attr('value', 1);
|
$f->attr('value', 1);
|
||||||
$f->attr('checked', $field->$name ? 'checked' : '');
|
$f->attr('checked', $field->$name ? 'checked' : '');
|
||||||
@@ -829,8 +864,9 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
$f->columnWidth = 50;
|
$f->columnWidth = 50;
|
||||||
$fieldset->append($f);
|
$fieldset->append($f);
|
||||||
|
|
||||||
|
/** @var InputfieldInteger $f */
|
||||||
|
$f = $modules->get('InputfieldInteger');
|
||||||
$name = 'deleteSpamDays';
|
$name = 'deleteSpamDays';
|
||||||
$f = $this->wire('modules')->get('InputfieldInteger');
|
|
||||||
$f->attr('name', $name);
|
$f->attr('name', $name);
|
||||||
$value = $field->$name;
|
$value = $field->$name;
|
||||||
if(is_null($value)) $value = 3; // default
|
if(is_null($value)) $value = 3; // default
|
||||||
@@ -842,13 +878,15 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
|
|
||||||
// ---------------------------------------
|
// ---------------------------------------
|
||||||
|
|
||||||
$fieldset = $this->wire('modules')->get('InputfieldFieldset');
|
/** @var InputfieldFieldset $fieldset */
|
||||||
|
$fieldset = $modules->get('InputfieldFieldset');
|
||||||
$fieldset->label = $this->_('Output');
|
$fieldset->label = $this->_('Output');
|
||||||
$fieldset->icon = 'comments-o';
|
$fieldset->icon = 'comments-o';
|
||||||
$inputfields->add($fieldset);
|
$inputfields->add($fieldset);
|
||||||
|
|
||||||
|
/** @var InputfieldInteger $f */
|
||||||
|
$f = $modules->get('InputfieldInteger');
|
||||||
$name = 'depth';
|
$name = 'depth';
|
||||||
$f = $this->wire('modules')->get('InputfieldInteger');
|
|
||||||
$f->attr('name', $name);
|
$f->attr('name', $name);
|
||||||
$f->attr('value', (int) $field->$name);
|
$f->attr('value', (int) $field->$name);
|
||||||
$f->label = $this->_('Reply depth');
|
$f->label = $this->_('Reply depth');
|
||||||
@@ -856,9 +894,9 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
$f->columnWidth = 50;
|
$f->columnWidth = 50;
|
||||||
$fieldset->append($f);
|
$fieldset->append($f);
|
||||||
|
|
||||||
|
/** @var InputfieldCheckbox $f */
|
||||||
|
$f = $modules->get('InputfieldCheckbox');
|
||||||
$name = 'sortNewest';
|
$name = 'sortNewest';
|
||||||
$f = $this->wire('modules')->get('InputfieldCheckbox');
|
|
||||||
$f->attr('name', $name);
|
$f->attr('name', $name);
|
||||||
$f->attr('value', 1);
|
$f->attr('value', 1);
|
||||||
$f->attr('checked', $field->$name ? 'checked' : '');
|
$f->attr('checked', $field->$name ? 'checked' : '');
|
||||||
@@ -866,9 +904,10 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
$f->description = $this->_('By default, comments will sort chronologically (oldest to newest). To reverse that behavior check this box.');
|
$f->description = $this->_('By default, comments will sort chronologically (oldest to newest). To reverse that behavior check this box.');
|
||||||
$f->columnWidth = 50;
|
$f->columnWidth = 50;
|
||||||
$fieldset->append($f);
|
$fieldset->append($f);
|
||||||
|
|
||||||
|
/** @var InputfieldCheckbox $f */
|
||||||
|
$f = $modules->get('InputfieldCheckbox');
|
||||||
$name = 'useWebsite';
|
$name = 'useWebsite';
|
||||||
$f = $this->wire('modules')->get('InputfieldCheckbox');
|
|
||||||
$f->attr('name', $name);
|
$f->attr('name', $name);
|
||||||
$f->attr('value', 1);
|
$f->attr('value', 1);
|
||||||
$f->attr('checked', $field->$name ? 'checked' : '');
|
$f->attr('checked', $field->$name ? 'checked' : '');
|
||||||
@@ -876,18 +915,20 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
$f->description = $this->_('When checked, the comment submission form will also include a website field.');
|
$f->description = $this->_('When checked, the comment submission form will also include a website field.');
|
||||||
$f->columnWidth = 50;
|
$f->columnWidth = 50;
|
||||||
$fieldset->append($f);
|
$fieldset->append($f);
|
||||||
|
|
||||||
|
/** @var InputfieldText $f */
|
||||||
|
$f = $modules->get('InputfieldText');
|
||||||
$name = 'dateFormat';
|
$name = 'dateFormat';
|
||||||
$f = $this->wire('modules')->get('InputfieldText');
|
|
||||||
$f->attr('name', $name);
|
$f->attr('name', $name);
|
||||||
$f->attr('value', $field->get('dateFormat') ? $field->get('dateFormat') : 'relative');
|
$f->attr('value', $field->get('dateFormat') ? $field->get('dateFormat') : 'relative');
|
||||||
$f->label = $this->_('Date/time format (for comment list)');
|
$f->label = $this->_('Date/time format (for comment list)');
|
||||||
$f->description = $this->_('Enter the date/time format you want the default comment list output to use. May be a PHP [date](http://php.net/manual/en/function.date.php) or [strftime](http://php.net/manual/en/function.strftime.php) format. May also be "relative" for relative date format.'); // dateFormat description
|
$f->description = $this->_('Enter the date/time format you want the default comment list output to use. May be a PHP [date](http://php.net/manual/en/function.date.php) or [strftime](http://php.net/manual/en/function.strftime.php) format. May also be "relative" for relative date format.'); // dateFormat description
|
||||||
$f->columnWidth = 50;
|
$f->columnWidth = 50;
|
||||||
$fieldset->append($f);
|
$fieldset->append($f);
|
||||||
|
|
||||||
|
/** @var InputfieldRadios $f */
|
||||||
|
$f = $modules->get('InputfieldRadios');
|
||||||
$name = 'useVotes';
|
$name = 'useVotes';
|
||||||
$f = $this->wire('modules')->get('InputfieldRadios');
|
|
||||||
$f->attr('name', $name);
|
$f->attr('name', $name);
|
||||||
$f->label = $this->_('Allow comment voting?');
|
$f->label = $this->_('Allow comment voting?');
|
||||||
$f->description = $this->_('Comment voting enables visitors to upvote and/or downvote comments. Vote counts are displayed alongside each comment. Only one upvote and/or downvote is allowed per comment, per IP address, per hour.');
|
$f->description = $this->_('Comment voting enables visitors to upvote and/or downvote comments. Vote counts are displayed alongside each comment. Only one upvote and/or downvote is allowed per comment, per IP address, per hour.');
|
||||||
@@ -898,8 +939,9 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
$f->columnWidth = 50;
|
$f->columnWidth = 50;
|
||||||
$fieldset->append($f);
|
$fieldset->append($f);
|
||||||
|
|
||||||
|
/** @var InputfieldRadios $f */
|
||||||
|
$f = $modules->get('InputfieldRadios');
|
||||||
$name = 'useStars';
|
$name = 'useStars';
|
||||||
$f = $this->wire('modules')->get('InputfieldRadios');
|
|
||||||
$f->attr('name', $name);
|
$f->attr('name', $name);
|
||||||
$f->label = $this->_('Use stars rating?');
|
$f->label = $this->_('Use stars rating?');
|
||||||
$f->description = $this->_('Star ratings enable the commenter to rate the subject they are commenting on, using a scale of 1 to 5 stars.');
|
$f->description = $this->_('Star ratings enable the commenter to rate the subject they are commenting on, using a scale of 1 to 5 stars.');
|
||||||
@@ -911,8 +953,9 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
$f->columnWidth = 50;
|
$f->columnWidth = 50;
|
||||||
$fieldset->append($f);
|
$fieldset->append($f);
|
||||||
|
|
||||||
|
/** @var InputfieldRadios $f */
|
||||||
|
$f = $modules->get('InputfieldRadios');
|
||||||
$name = 'useGravatar';
|
$name = 'useGravatar';
|
||||||
$f = $this->wire('modules')->get('InputfieldRadios');
|
|
||||||
$f->attr('name', $name);
|
$f->attr('name', $name);
|
||||||
$f->addOption('', $disabledLabel);
|
$f->addOption('', $disabledLabel);
|
||||||
$f->addOption('g', $this->_('G: Suitable for display on all websites with any audience type.'));
|
$f->addOption('g', $this->_('G: Suitable for display on all websites with any audience type.'));
|
||||||
@@ -944,23 +987,26 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
|
|
||||||
$fieldset = $this->wire('modules')->get('InputfieldFieldset');
|
/** @var InputfieldFieldset $fieldset */
|
||||||
|
$fieldset = $modules->get('InputfieldFieldset');
|
||||||
$fieldset->label = $this->_('Implementation');
|
$fieldset->label = $this->_('Implementation');
|
||||||
$fieldset->icon = 'file-code-o';
|
$fieldset->icon = 'file-code-o';
|
||||||
$fieldset->description = $this->_('This section is here to help you get started with outputting comments on the front-end of your site. Everything here is optional.');
|
$fieldset->description = $this->_('This section is here to help you get started with outputting comments on the front-end of your site. Everything here is optional.');
|
||||||
$fieldset->notes = $this->_('If using a cache for output, configure it to bypass the cache when the GET variable "comment_success" is present.');
|
$fieldset->notes = $this->_('If using a cache for output, configure it to bypass the cache when the GET variable "comment_success" is present.');
|
||||||
$inputfields->add($fieldset);
|
$inputfields->add($fieldset);
|
||||||
|
|
||||||
$f = $this->wire('modules')->get('InputfieldMarkup');
|
/** @var InputfieldMarkup $f */
|
||||||
|
$f = $modules->get('InputfieldMarkup');
|
||||||
$f->label = $this->_('PHP code to output comments');
|
$f->label = $this->_('PHP code to output comments');
|
||||||
$f->value =
|
$f->value =
|
||||||
"<p>Please copy and paste the following into your template file(s) where you would like the comments to be output:</p>" .
|
"<p>Please copy and paste the following into your template file(s) where you would like the comments to be output:</p>" .
|
||||||
"<pre style='border-left: 4px solid #ccc; padding-left: 1em;'><?php echo \$page->{$field->name}->renderAll(); ?></pre>" .
|
"<pre style='border-left: 4px solid #ccc; padding-left: 1em;'><?php echo \$page->{$field->name}->renderAll(); ?></pre>" .
|
||||||
"<p>For more options please see the <a href='https://processwire.com/api/fieldtypes/comments/' target='_blank'>comments documentation page</a>.</p>";
|
"<p>For more options please see the <a href='https://processwire.com/api/fieldtypes/comments/' target='_blank'>comments documentation page</a>.</p>";
|
||||||
$fieldset->add($f);
|
$fieldset->add($f);
|
||||||
|
|
||||||
$f = $this->wire('modules')->get('InputfieldMarkup');
|
/** @var InputfieldMarkup $f */
|
||||||
|
$f = $modules->get('InputfieldMarkup');
|
||||||
$f->label = $this->_('CSS for front-end comments output');
|
$f->label = $this->_('CSS for front-end comments output');
|
||||||
$ftUrl = $this->wire('config')->urls('FieldtypeComments');
|
$ftUrl = $this->wire('config')->urls('FieldtypeComments');
|
||||||
$f->value =
|
$f->value =
|
||||||
@@ -969,8 +1015,9 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
"<p>Or if you prefer, copy the <a target='_blank' href='{$ftUrl}comments.css'>comments.css</a> file to your own location, " .
|
"<p>Or if you prefer, copy the <a target='_blank' href='{$ftUrl}comments.css'>comments.css</a> file to your own location, " .
|
||||||
"modify it as desired, and link to it in your document head as you do with your other css files.</p>";
|
"modify it as desired, and link to it in your document head as you do with your other css files.</p>";
|
||||||
$fieldset->add($f);
|
$fieldset->add($f);
|
||||||
|
|
||||||
$f = $this->wire('modules')->get('InputfieldMarkup');
|
/** @var InputfieldMarkup $f */
|
||||||
|
$f = $modules->get('InputfieldMarkup');
|
||||||
$f->label = $this->_('JS for front-end comments output');
|
$f->label = $this->_('JS for front-end comments output');
|
||||||
$f->value =
|
$f->value =
|
||||||
"<p>If you are using threaded comments (i.e. reply depth > 0), please also copy and paste the following into the document <code><head></code> " .
|
"<p>If you are using threaded comments (i.e. reply depth > 0), please also copy and paste the following into the document <code><head></code> " .
|
||||||
@@ -979,9 +1026,10 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
"<p>Like with the comments.css file, feel free to copy and link to the <a target='_blank' href='{$ftUrl}comments.js'>comments.js</a> file from your own " .
|
"<p>Like with the comments.css file, feel free to copy and link to the <a target='_blank' href='{$ftUrl}comments.js'>comments.js</a> file from your own " .
|
||||||
"location if you prefer it.</p>";
|
"location if you prefer it.</p>";
|
||||||
$fieldset->add($f);
|
$fieldset->add($f);
|
||||||
|
|
||||||
|
/** @var InputfieldHidden $f */
|
||||||
|
$f = $modules->get('InputfieldHidden');
|
||||||
$name = 'schemaVersion';
|
$name = 'schemaVersion';
|
||||||
$f = $this->wire('modules')->get('InputfieldHidden');
|
|
||||||
$f->attr('name', $name);
|
$f->attr('name', $name);
|
||||||
$value = (int) $field->$name;
|
$value = (int) $field->$name;
|
||||||
$f->attr('value', $value);
|
$f->attr('value', $value);
|
||||||
@@ -1014,9 +1062,10 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static public function findComments($field, $selectorString) {
|
static public function findComments($field, $selectorString) {
|
||||||
if(is_string($field)) $field = wire('fields')->get($field);
|
if(is_string($field)) $field = wire()->fields->get($field);
|
||||||
if(!$field instanceof Field) throw new WireException('Arg 1 to findComments() must be a field');
|
if(!$field instanceof Field) throw new WireException('Arg 1 to findComments() must be a field');
|
||||||
return $field->type->find($field, $selectorString);
|
$fieldtype = $field->type; /** @var FieldtypeComments $fieldtype */
|
||||||
|
return $fieldtype->find($field, $selectorString);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1070,7 +1119,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
// arguments are reversed
|
// arguments are reversed
|
||||||
list($selectorString, $field) = array($field, $selectorString);
|
list($selectorString, $field) = array($field, $selectorString);
|
||||||
}
|
}
|
||||||
if(is_string($field)) $field = $this->wire('fields')->get($field);
|
if(is_string($field)) $field = $this->wire()->fields->get($field);
|
||||||
}
|
}
|
||||||
if(!$field instanceof Field) $field = $this->getLastAccessField();
|
if(!$field instanceof Field) $field = $this->getLastAccessField();
|
||||||
if(!$field instanceof Field) $field = $this->getCommentsFields(true);
|
if(!$field instanceof Field) $field = $this->getCommentsFields(true);
|
||||||
@@ -1106,8 +1155,10 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
$limit = 10;
|
$limit = 10;
|
||||||
$start = 0;
|
$start = 0;
|
||||||
$sorts = array();
|
$sorts = array();
|
||||||
$database = $this->wire('database');
|
$database = $this->wire()->database;
|
||||||
|
$fields = $this->wire()->fields;
|
||||||
|
$pages = $this->wire()->pages;
|
||||||
|
|
||||||
$selectQuery = new DatabaseQuerySelect();
|
$selectQuery = new DatabaseQuerySelect();
|
||||||
$countQuery = new DatabaseQuerySelect();
|
$countQuery = new DatabaseQuerySelect();
|
||||||
|
|
||||||
@@ -1251,7 +1302,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
/** @var Field $f */
|
/** @var Field $f */
|
||||||
$f = $this->wire('fields')->get($fieldName);
|
$f = $fields->get($fieldName);
|
||||||
if(!$f) continue;
|
if(!$f) continue;
|
||||||
$fieldTable = $f->getTable();
|
$fieldTable = $f->getTable();
|
||||||
if(!$database->isOperator($operator)) $operator = '=';
|
if(!$database->isOperator($operator)) $operator = '=';
|
||||||
@@ -1275,7 +1326,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if no status was specified and we’re on the front-end, match only approved comments
|
// if no status was specified and we’re on the front-end, match only approved comments
|
||||||
if($status === null && $this->wire('page')->template != 'admin') {
|
if($status === null && $this->wire()->page->template->name != 'admin') {
|
||||||
$wheres[] = "$table.status>=" . Comment::statusApproved;
|
$wheres[] = "$table.status>=" . Comment::statusApproved;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1334,20 +1385,14 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
$commentPages = array();
|
$commentPages = array();
|
||||||
|
|
||||||
while($row = $query->fetch(\PDO::FETCH_ASSOC)) {
|
while($row = $query->fetch(\PDO::FETCH_ASSOC)) {
|
||||||
$comment = $this->wire(new Comment());
|
|
||||||
$comment->setField($field);
|
|
||||||
foreach($row as $key => $value) {
|
|
||||||
if($key == 'data') $key = 'text';
|
|
||||||
$comment->set($key, $value);
|
|
||||||
}
|
|
||||||
$pageID = $row['pages_id'];
|
$pageID = $row['pages_id'];
|
||||||
if(isset($commentPages[$pageID])) {
|
if(isset($commentPages[$pageID])) {
|
||||||
$page = $commentPages[$pageID];
|
$page = $commentPages[$pageID];
|
||||||
} else {
|
} else {
|
||||||
$page = $this->wire('pages')->get((int) $pageID);
|
$page = $pages->get((int) $pageID);
|
||||||
$commentPages[$page->id] = $page;
|
$commentPages[$page->id] = $page;
|
||||||
}
|
}
|
||||||
$comment->resetTrackChanges(true);
|
$comment = $this->makeComment($page, $field, $row);
|
||||||
$comments->add($comment);
|
$comments->add($comment);
|
||||||
if($page->id) $comment->setPage($page);
|
if($page->id) $comment->setPage($page);
|
||||||
$comment->setIsLoaded(true);
|
$comment->setIsLoaded(true);
|
||||||
@@ -1382,7 +1427,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
*/
|
*/
|
||||||
public function getCommentsFields($one = false) {
|
public function getCommentsFields($one = false) {
|
||||||
$fields = array();
|
$fields = array();
|
||||||
foreach($this->wire('fields') as $field) {
|
foreach($this->wire()->fields as $field) {
|
||||||
if($field->type instanceof FieldtypeComments) {
|
if($field->type instanceof FieldtypeComments) {
|
||||||
$fields[] = $field;
|
$fields[] = $field;
|
||||||
if($one) break;
|
if($one) break;
|
||||||
@@ -1402,10 +1447,10 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function getCommentByCode($page, $field, $code) {
|
public function getCommentByCode($page, $field, $code) {
|
||||||
if(!is_object($page)) $page = $this->wire('pages')->get((int) $page);
|
if(!is_object($page)) $page = $this->wire()->pages->get((int) $page);
|
||||||
if(!$page->id) return null;
|
if(!$page->id) return null;
|
||||||
if(!trim($code)) return null;
|
if(!trim($code)) return null;
|
||||||
if(!is_object($field)) $field = $this->wire('fields')->get($this->wire('sanitizer')->fieldName($field));
|
if(!is_object($field)) $field = $this->wire()->fields->get($this->wire()->sanitizer->fieldName($field));
|
||||||
if(!$field || !$field->type instanceof FieldtypeComments) return null;
|
if(!$field || !$field->type instanceof FieldtypeComments) return null;
|
||||||
$table = $field->getTable();
|
$table = $field->getTable();
|
||||||
$col = strlen($code) > 100 ? 'code' : 'subcode';
|
$col = strlen($code) > 100 ? 'code' : 'subcode';
|
||||||
@@ -1429,26 +1474,27 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function getCommentByID($page, $field, $id) {
|
public function getCommentByID($page, $field, $id) {
|
||||||
|
$pages = $this->wire()->pages;
|
||||||
if(empty($id)) return null;
|
if(empty($id)) return null;
|
||||||
if($page && !is_object($page)) {
|
if($page && !is_object($page)) {
|
||||||
$page = $this->wire('pages')->get((int) $page);
|
$page = $pages->get((int) $page);
|
||||||
if(!$page->id) return null;
|
if(!$page->id) return null;
|
||||||
}
|
}
|
||||||
if(!is_object($field) && $field) {
|
if(!is_object($field) && $field) {
|
||||||
$field = $this->wire('fields')->get($this->wire('sanitizer')->fieldName($field));
|
$field = $this->wire()->fields->get($this->wire()->sanitizer->fieldName($field));
|
||||||
}
|
}
|
||||||
if(!$field || !$field->type instanceof FieldtypeComments) return null;
|
if(!$field || !$field->type instanceof FieldtypeComments) return null;
|
||||||
$table = $field->getTable();
|
$table = $field->getTable();
|
||||||
$sql = "SELECT * FROM `$table` WHERE id=:id ";
|
$sql = "SELECT * FROM `$table` WHERE id=:id ";
|
||||||
if($page) $sql .= "AND pages_id=:pageID";
|
if($page) $sql .= "AND pages_id=:pageID";
|
||||||
$query = $this->wire('database')->prepare($sql);
|
$query = $this->wire()->database->prepare($sql);
|
||||||
$query->bindValue(':id', (int) $id, \PDO::PARAM_INT);
|
$query->bindValue(':id', (int) $id, \PDO::PARAM_INT);
|
||||||
if($page) $query->bindValue(':pageID', $page->id, \PDO::PARAM_INT);
|
if($page) $query->bindValue(':pageID', $page->id, \PDO::PARAM_INT);
|
||||||
if(!$query->execute()) return null;
|
if(!$query->execute()) return null;
|
||||||
if(!$query->rowCount()) return null;
|
if(!$query->rowCount()) return null;
|
||||||
$data = $query->fetch(\PDO::FETCH_ASSOC);
|
$data = $query->fetch(\PDO::FETCH_ASSOC);
|
||||||
if(!$page) {
|
if(!$page) {
|
||||||
$page = $this->wire('pages')->get((int) $data['pages_id']);
|
$page = $pages->get((int) $data['pages_id']);
|
||||||
}
|
}
|
||||||
return $this->makeComment($page, $field, $data);
|
return $this->makeComment($page, $field, $data);
|
||||||
}
|
}
|
||||||
@@ -1493,15 +1539,26 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected function makeComment($page, $field, array $data) {
|
protected function makeComment($page, $field, array $data) {
|
||||||
|
|
||||||
|
/** @var Comment $comment */
|
||||||
$comment = $this->wire(new Comment());
|
$comment = $this->wire(new Comment());
|
||||||
$comment->setPage($page);
|
$comment->setPage($page);
|
||||||
$comment->setField($field);
|
$comment->setField($field);
|
||||||
|
|
||||||
foreach($data as $key => $val) {
|
foreach($data as $key => $val) {
|
||||||
if($key == 'data') $key = 'text';
|
if($key === 'data') {
|
||||||
|
$key = 'text';
|
||||||
|
} else if($key === 'meta') {
|
||||||
|
$val = is_string($val) ? json_decode($val, true) : array();
|
||||||
|
if(is_array($val)) $comment->setMeta($val);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$comment->set($key, $val);
|
$comment->set($key, $val);
|
||||||
}
|
}
|
||||||
|
|
||||||
$comment->resetTrackChanges(true);
|
$comment->resetTrackChanges(true);
|
||||||
$comment->setIsLoaded(true);
|
$comment->setIsLoaded(true);
|
||||||
|
|
||||||
return $comment;
|
return $comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1530,11 +1587,18 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
$sql = "UPDATE `$table` SET ";
|
$sql = "UPDATE `$table` SET ";
|
||||||
$values = array();
|
$values = array();
|
||||||
foreach($properties as $property => $value) {
|
foreach($properties as $property => $value) {
|
||||||
$comment->set($property, $value);
|
if($property === 'meta') {
|
||||||
|
if(!is_array($value)) continue;
|
||||||
|
$comment->setMeta($value);
|
||||||
|
$value = json_encode($value);
|
||||||
|
if(!is_string($value)) continue;
|
||||||
|
} else {
|
||||||
|
$comment->set($property, $value);
|
||||||
|
}
|
||||||
$property = $sanitizer->fieldName($property);
|
$property = $sanitizer->fieldName($property);
|
||||||
$property = $database->escapeCol($property);
|
$property = $database->escapeCol($property);
|
||||||
if($property == 'text') $property = 'data';
|
if($property === 'text') $property = 'data';
|
||||||
if(is_null($value) && ($property == 'code' || $property == 'subcode')) {
|
if(is_null($value) && ($property === 'code' || $property === 'subcode')) {
|
||||||
$sql .= "`$property`=NULL, ";
|
$sql .= "`$property`=NULL, ";
|
||||||
} else {
|
} else {
|
||||||
$sql .= "`$property`=:$property, ";
|
$sql .= "`$property`=:$property, ";
|
||||||
@@ -1598,8 +1662,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
throw new WireException("Comment is already assigned to a different Field");
|
throw new WireException("Comment is already assigned to a different Field");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var WireDatabasePDO $database */
|
$database = $this->wire()->database;
|
||||||
$database = $this->wire('database');
|
|
||||||
$table = $database->escapeTable($field->table);
|
$table = $database->escapeTable($field->table);
|
||||||
$sets = array('pages_id=:pages_id');
|
$sets = array('pages_id=:pages_id');
|
||||||
$binds = array('pages_id' => (int) $page->id);
|
$binds = array('pages_id' => (int) $page->id);
|
||||||
@@ -1735,7 +1798,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected function getMaxSort(Page $page, Field $field) {
|
protected function getMaxSort(Page $page, Field $field) {
|
||||||
$database = $this->wire('database');
|
$database = $this->wire()->database;
|
||||||
$table = $database->escapeTable($field->getTable());
|
$table = $database->escapeTable($field->getTable());
|
||||||
$sql = "SELECT MAX(sort) FROM `$table` WHERE pages_id=:pages_id";
|
$sql = "SELECT MAX(sort) FROM `$table` WHERE pages_id=:pages_id";
|
||||||
$query = $database->prepare($sql);
|
$query = $database->prepare($sql);
|
||||||
@@ -1781,7 +1844,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
);
|
);
|
||||||
|
|
||||||
$options = array_merge($defaults, $options);
|
$options = array_merge($defaults, $options);
|
||||||
$database = $this->wire('database');
|
$database = $this->wire()->database;
|
||||||
$table = $database->escapeTable($field->getTable());
|
$table = $database->escapeTable($field->getTable());
|
||||||
$sql = "SELECT COUNT(*) FROM `$table` WHERE pages_id=:page ";
|
$sql = "SELECT COUNT(*) FROM `$table` WHERE pages_id=:page ";
|
||||||
$binds = array(':page' => $page->id);
|
$binds = array(':page' => $page->id);
|
||||||
@@ -1871,7 +1934,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
*/
|
*/
|
||||||
public function ___commentApproved(Page $page, Field $field, Comment $comment, $notes = '') {
|
public function ___commentApproved(Page $page, Field $field, Comment $comment, $notes = '') {
|
||||||
|
|
||||||
$this->wire('log')->message("Approved comment $comment->id - $notes");
|
$this->wire()->log->message("Approved comment $comment->id - $notes");
|
||||||
|
|
||||||
if(!$field->get('useNotify')) return; // notifications not in use
|
if(!$field->get('useNotify')) return; // notifications not in use
|
||||||
if($comment->flags & Comment::flagNotifyQueue) return; // comment queued for 3rd party notifications
|
if($comment->flags & Comment::flagNotifyQueue) return; // comment queued for 3rd party notifications
|
||||||
@@ -2052,7 +2115,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
*/
|
*/
|
||||||
public function voteComment(Page $page, Field $field, Comment $comment, $up = true) {
|
public function voteComment(Page $page, Field $field, Comment $comment, $up = true) {
|
||||||
|
|
||||||
$database = $this->wire('database');
|
$database = $this->wire()->database;
|
||||||
$table = $database->escapeTable($field->getTable()) . '_votes';
|
$table = $database->escapeTable($field->getTable()) . '_votes';
|
||||||
|
|
||||||
if(!$field->get('useVotes')) return false;
|
if(!$field->get('useVotes')) return false;
|
||||||
@@ -2062,8 +2125,8 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
$query = $database->prepare($sql);
|
$query = $database->prepare($sql);
|
||||||
$query->bindValue(':comment_id', $comment->id, \PDO::PARAM_INT);
|
$query->bindValue(':comment_id', $comment->id, \PDO::PARAM_INT);
|
||||||
$query->bindValue(':vote', $up ? 1 : -1, \PDO::PARAM_INT);
|
$query->bindValue(':vote', $up ? 1 : -1, \PDO::PARAM_INT);
|
||||||
$query->bindValue(':ip', $this->wire('session')->getIP(), \PDO::PARAM_STR);
|
$query->bindValue(':ip', $this->wire()->session->getIP(), \PDO::PARAM_STR);
|
||||||
$query->bindValue(':user_id', $this->wire('user')->id, \PDO::PARAM_INT);
|
$query->bindValue(':user_id', $this->wire()->user->id, \PDO::PARAM_INT);
|
||||||
|
|
||||||
$result = false;
|
$result = false;
|
||||||
|
|
||||||
@@ -2083,7 +2146,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
if(stripos($error, 'duplicate entry')) {
|
if(stripos($error, 'duplicate entry')) {
|
||||||
$this->error($this->_('You have already voted for this comment'));
|
$this->error($this->_('You have already voted for this comment'));
|
||||||
} else {
|
} else {
|
||||||
if($this->wire('config')->debug && !$this->wire('user')->isLoggedin()) {
|
if($this->wire()->config->debug && !$this->wire()->user->isLoggedin()) {
|
||||||
$this->error($e->getMessage());
|
$this->error($e->getMessage());
|
||||||
} else {
|
} else {
|
||||||
$this->error($this->_('Error recording vote'));
|
$this->error($this->_('Error recording vote'));
|
||||||
@@ -2104,6 +2167,8 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
*/
|
*/
|
||||||
public function checkVoteAction($page) {
|
public function checkVoteAction($page) {
|
||||||
|
|
||||||
|
$input = $this->wire()->input;
|
||||||
|
|
||||||
$result = array(
|
$result = array(
|
||||||
'success' => false,
|
'success' => false,
|
||||||
'valid' => false,
|
'valid' => false,
|
||||||
@@ -2115,14 +2180,14 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
'commentID' => 0,
|
'commentID' => 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
$action = $this->wire('input')->get('comment_success');
|
$action = $input->get('comment_success');
|
||||||
if($action !== 'upvote' && $action !== 'downvote') return $result;
|
if($action !== 'upvote' && $action !== 'downvote') return $result;
|
||||||
|
|
||||||
$commentID = (int) $this->wire('input')->get('comment_id');
|
$commentID = (int) $input->get('comment_id');
|
||||||
$fieldID = (int) $this->wire('input')->get('field_id');
|
$fieldID = (int) $input->get('field_id');
|
||||||
if(!$commentID || !$fieldID) return $result;
|
if(!$commentID || !$fieldID) return $result;
|
||||||
|
|
||||||
$field = $this->wire('fields')->get($fieldID);
|
$field = $this->wire()->fields->get($fieldID);
|
||||||
if(!$field || !$field->type instanceof FieldtypeComments) return $result;
|
if(!$field || !$field->type instanceof FieldtypeComments) return $result;
|
||||||
|
|
||||||
if($page instanceof HookEvent) $page = $page->object;
|
if($page instanceof HookEvent) $page = $page->object;
|
||||||
@@ -2145,7 +2210,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
'commentID' => $comment->id
|
'commentID' => $comment->id
|
||||||
);
|
);
|
||||||
|
|
||||||
if($this->wire('config')->ajax) {
|
if($this->wire()->config->ajax) {
|
||||||
header("Content-type: application/json");
|
header("Content-type: application/json");
|
||||||
echo json_encode($result);
|
echo json_encode($result);
|
||||||
exit;
|
exit;
|
||||||
@@ -2164,7 +2229,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function ___deleteField(Field $field) {
|
public function ___deleteField(Field $field) {
|
||||||
$database = $this->wire('database');
|
$database = $this->wire()->database;
|
||||||
$table = $database->escapeTable($field->table);
|
$table = $database->escapeTable($field->table);
|
||||||
try {
|
try {
|
||||||
$result = $database->exec("DROP TABLE `$table`"); // QA
|
$result = $database->exec("DROP TABLE `$table`"); // QA
|
||||||
@@ -2194,7 +2259,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
*/
|
*/
|
||||||
public function ___renamedField(Field $field, $prevName) {
|
public function ___renamedField(Field $field, $prevName) {
|
||||||
|
|
||||||
$database = $this->wire('database');
|
$database = $this->wire()->database;
|
||||||
$table = $database->escapeTable(Field::tablePrefix . $field->name . '_votes');
|
$table = $database->escapeTable(Field::tablePrefix . $field->name . '_votes');
|
||||||
$prevTable = $database->escapeTable(Field::tablePrefix . $prevName . '_votes');
|
$prevTable = $database->escapeTable(Field::tablePrefix . $prevName . '_votes');
|
||||||
|
|
||||||
@@ -2272,7 +2337,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
protected function exportComment($comment) {
|
protected function exportComment($comment) {
|
||||||
if(is_object($comment)) $comment = $comment->getArray();
|
if(is_object($comment)) $comment = $comment->getArray();
|
||||||
if(isset($comment['created_users_id'])) {
|
if(isset($comment['created_users_id'])) {
|
||||||
$u = $this->wire('users')->get((int) $comment['created_users_id']);
|
$u = $this->wire()->users->get((int) $comment['created_users_id']);
|
||||||
$comment['created_user'] = $u->name;
|
$comment['created_user'] = $u->name;
|
||||||
unset($comment['created_users_id']);
|
unset($comment['created_users_id']);
|
||||||
}
|
}
|
||||||
@@ -2352,6 +2417,9 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
*/
|
*/
|
||||||
public function ___importValue(Page $page, Field $field, $value, array $options = array()) {
|
public function ___importValue(Page $page, Field $field, $value, array $options = array()) {
|
||||||
|
|
||||||
|
$users = $this->wire()->users;
|
||||||
|
$sanitizer = $this->wire()->sanitizer;
|
||||||
|
|
||||||
$value = $this->exportComments($value);
|
$value = $this->exportComments($value);
|
||||||
$comments = $page->get($field->name);
|
$comments = $page->get($field->name);
|
||||||
$commentsArray = array();
|
$commentsArray = array();
|
||||||
@@ -2408,7 +2476,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
|
|
||||||
foreach($addComments as $commentArray) {
|
foreach($addComments as $commentArray) {
|
||||||
unset($commentArray['id']);
|
unset($commentArray['id']);
|
||||||
$u = $this->wire('users')->get("name=" . $this->wire('sanitizer')->pageName($commentArray['created_user']));
|
$u = $users->get("name=" . $sanitizer->pageName($commentArray['created_user']));
|
||||||
$commentArray['created_users_id'] = $u->id;
|
$commentArray['created_users_id'] = $u->id;
|
||||||
unset($commentArray['created_user']);
|
unset($commentArray['created_user']);
|
||||||
$comment = $this->makeComment($page, $field, $commentArray);
|
$comment = $this->makeComment($page, $field, $commentArray);
|
||||||
|
@@ -5,9 +5,10 @@
|
|||||||
*
|
*
|
||||||
* An Inputfield for handling administration of Comments.
|
* An Inputfield for handling administration of Comments.
|
||||||
*
|
*
|
||||||
* ProcessWire 3.x, Copyright 2019 by Ryan Cramer
|
* ProcessWire 3.x, Copyright 2022 by Ryan Cramer
|
||||||
* https://processwire.com
|
* https://processwire.com
|
||||||
*
|
*
|
||||||
|
* @property bool|int $useManager
|
||||||
* @method InputfieldMarkup renderItem(Comment $comment, $n)
|
* @method InputfieldMarkup renderItem(Comment $comment, $n)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -25,11 +26,29 @@ class InputfieldCommentsAdmin extends Inputfield implements InputfieldItemList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected $commentIDsToNumbers = array();
|
protected $commentIDsToNumbers = array();
|
||||||
|
|
||||||
|
protected $commentsManagerUrl = '';
|
||||||
|
|
||||||
|
protected $statuses = array();
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->set('useManager', false);
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
public function init() {
|
public function init() {
|
||||||
parent::init();
|
parent::init();
|
||||||
|
if($this->wire()->modules->isInstalled('ProcessCommentsManager')) {
|
||||||
|
$this->commentsManagerUrl = $this->wire()->config->urls->admin . 'setup/comments/';
|
||||||
|
}
|
||||||
|
$this->statuses = array(
|
||||||
|
Comment::statusFeatured => array($this->_x('Featured', 'comment-status'), 'trophy', 'featured'),
|
||||||
|
Comment::statusApproved => array($this->_x('Approved', 'comment-status'), 'check-circle', 'approved'),
|
||||||
|
Comment::statusPending => array($this->_x('Pending', 'comment-status'), 'commenting-o', 'pending'),
|
||||||
|
Comment::statusSpam => array($this->_x('Spam', 'comment-status'), 'warning', 'spam'),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Comment $comment
|
* @param Comment $comment
|
||||||
* @param int $n
|
* @param int $n
|
||||||
@@ -37,14 +56,7 @@ class InputfieldCommentsAdmin extends Inputfield implements InputfieldItemList {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected function ___renderItem(Comment $comment, $n) {
|
protected function ___renderItem(Comment $comment, $n) {
|
||||||
|
|
||||||
$statuses = array(
|
|
||||||
Comment::statusFeatured => array($this->_x('Featured', 'comment-status'), 'trophy'),
|
|
||||||
Comment::statusApproved => array($this->_x('Approved', 'comment-status'), 'check-circle'),
|
|
||||||
Comment::statusPending => array($this->_x('Pending', 'comment-status'), 'question-circle'),
|
|
||||||
Comment::statusSpam => array($this->_x('Spam', 'comment-status'), 'warning'),
|
|
||||||
);
|
|
||||||
|
|
||||||
$name = $this->name;
|
$name = $this->name;
|
||||||
$names = array(
|
$names = array(
|
||||||
'status' => "{$this->name}_status_{$comment->id}",
|
'status' => "{$this->name}_status_{$comment->id}",
|
||||||
@@ -57,13 +69,13 @@ class InputfieldCommentsAdmin extends Inputfield implements InputfieldItemList {
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
$sanitizer = $this->wire('sanitizer');
|
$sanitizer = $this->wire()->sanitizer;
|
||||||
$statusName = '';
|
$statusName = '';
|
||||||
$statusIcon = '';
|
$statusIcon = '';
|
||||||
$statusOut = "<select id='$names[status]' name='$names[status]'>";
|
$statusOut = "<select id='$names[status]' name='$names[status]'>";
|
||||||
|
|
||||||
foreach($statuses as $status => $statusInfo) {
|
foreach($this->statuses as $status => $statusInfo) {
|
||||||
list($label, $icon) = $statusInfo;
|
list($label, $icon, /*$name*/) = $statusInfo;
|
||||||
if($comment->status == $status) {
|
if($comment->status == $status) {
|
||||||
$selected = " selected='selected'";
|
$selected = " selected='selected'";
|
||||||
$statusName = $label;
|
$statusName = $label;
|
||||||
@@ -145,6 +157,21 @@ class InputfieldCommentsAdmin extends Inputfield implements InputfieldItemList {
|
|||||||
} else {
|
} else {
|
||||||
$starsInput = '';
|
$starsInput = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$notes = array();
|
||||||
|
if($notifyOut) {
|
||||||
|
$notes[] = $this->_('Email notifications:') . " $notifyOut";
|
||||||
|
}
|
||||||
|
if($this->commentsManagerUrl) {
|
||||||
|
$metaQty = count($comment->getMeta());
|
||||||
|
$page = $comment->getPage();
|
||||||
|
$field = $comment->getField();
|
||||||
|
$metaUrl = $this->commentsManagerUrl . "meta/?comment_id=$comment->id&page_id=$page->id&field_id=$field->id";
|
||||||
|
// $editUrl = $this->commentsManagerUrl . "list/$field->name/all/?id=$comment->id";
|
||||||
|
$notes[] =
|
||||||
|
"<a href='$metaUrl' class='pw-modal' data-buttons='button'>" .
|
||||||
|
sprintf($this->_n('%d meta value', '%d meta values', $metaQty), $metaQty) . "</a>";
|
||||||
|
}
|
||||||
|
|
||||||
$f->value =
|
$f->value =
|
||||||
"<div class='ui-helper-clearfix'>" .
|
"<div class='ui-helper-clearfix'>" .
|
||||||
@@ -175,7 +202,7 @@ class InputfieldCommentsAdmin extends Inputfield implements InputfieldItemList {
|
|||||||
"<label for='$names[text]'><span class='detail'>" . $this->_('Text') . "</span></label>" .
|
"<label for='$names[text]'><span class='detail'>" . $this->_('Text') . "</span></label>" .
|
||||||
"<textarea id='$names[text]' name='$names[text]' rows='5'>$text</textarea>" .
|
"<textarea id='$names[text]' name='$names[text]' rows='5'>$text</textarea>" .
|
||||||
"</p>" .
|
"</p>" .
|
||||||
($notifyOut ? "<p class='CommentsAdminItemNotify notes'>" . $this->_('Email notifications:') . " $notifyOut</p>" : "") .
|
(count($notes) ? "<p class='CommentsAdminItemNotify detail'>" . implode(' • ', $notes) . "</p>" : "") .
|
||||||
"<input class='CommentsAdminItemSort' type='hidden' name='sort_{$this->name}_{$comment->id}' value='$n' />" .
|
"<input class='CommentsAdminItemSort' type='hidden' name='sort_{$this->name}_{$comment->id}' value='$n' />" .
|
||||||
"";
|
"";
|
||||||
|
|
||||||
@@ -184,30 +211,79 @@ class InputfieldCommentsAdmin extends Inputfield implements InputfieldItemList {
|
|||||||
|
|
||||||
public function ___render() {
|
public function ___render() {
|
||||||
|
|
||||||
if(!count($this->value)) return "<p>" . $this->_('There are currently no items to display.') . "</p>";
|
$value = $this->value;
|
||||||
|
|
||||||
|
if($this->useManager || !count($value)) {
|
||||||
|
$out = $this->renderValue();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$n = 0;
|
||||||
|
foreach($value as $comment) {
|
||||||
|
$this->commentIDsToNumbers[$comment->id] = ++$n;
|
||||||
|
}
|
||||||
|
|
||||||
$n = 0;
|
$fieldset = new InputfieldWrapper(); // wired
|
||||||
foreach($this->value as $comment) {
|
$this->wire($fieldset);
|
||||||
$this->commentIDsToNumbers[$comment->id] = ++$n;
|
|
||||||
|
$n = 0;
|
||||||
|
foreach($value as $comment) {
|
||||||
|
$f = $this->renderItem($comment, $n++);
|
||||||
|
$f->addClass($this->wrapClass);
|
||||||
|
$fieldset->add($f);
|
||||||
|
}
|
||||||
|
|
||||||
|
$out = $fieldset->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
$fieldset = new InputfieldWrapper(); // wired
|
|
||||||
$this->wire($fieldset);
|
|
||||||
|
|
||||||
$n = 0;
|
|
||||||
foreach($this->value as $comment) {
|
|
||||||
$f = $this->renderItem($comment, $n++);
|
|
||||||
$f->addClass($this->wrapClass);
|
|
||||||
$fieldset->add($f);
|
|
||||||
}
|
|
||||||
|
|
||||||
$out = $fieldset->render();
|
|
||||||
//$this->addClass('InputfieldFieldset', 'wrapClass');
|
|
||||||
|
|
||||||
return $out;
|
return $out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function ___renderValue() {
|
||||||
|
|
||||||
|
$value = $this->attr('value');
|
||||||
|
|
||||||
|
if(!count($value)) {
|
||||||
|
return "<p>" . $this->_('There are currently no items to display.') . "</p>";
|
||||||
|
}
|
||||||
|
|
||||||
|
$items = array();
|
||||||
|
$qtys = array();
|
||||||
|
$total = 0;
|
||||||
|
$field = null;
|
||||||
|
$page = null;
|
||||||
|
|
||||||
|
foreach($value as $comment) {
|
||||||
|
/** @var Comment $comment */
|
||||||
|
$total++;
|
||||||
|
if(!$field) $field = $comment->getField();
|
||||||
|
if(!$page) $page = $comment->getPage();
|
||||||
|
$status = $comment->status;
|
||||||
|
if(!isset($this->statuses[$status])) continue;
|
||||||
|
if(!isset($qtys[$status])) $qtys[$status] = 0;
|
||||||
|
$qtys[$status]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$url = $this->commentsManagerUrl . "list/$field->name/all/?pages_id=$page->id";
|
||||||
|
$icon = wireIconMarkup('comments');
|
||||||
|
$item = $icon . ' ' . sprintf($this->_n('%d comment', '%d comments', $total), $total);
|
||||||
|
|
||||||
|
if($page->editable($field)) $item = "<a href='$url' target='_blank'>$item</a>";
|
||||||
|
$items[] = $item;
|
||||||
|
|
||||||
|
foreach($this->statuses as $status => $statusInfo) {
|
||||||
|
if(empty($qtys[$status])) continue;
|
||||||
|
$qty = $qtys[$status];
|
||||||
|
list($label, $icon, /*$name*/) = $statusInfo;
|
||||||
|
$icon = wireIconMarkup($icon);
|
||||||
|
$items[] = "<span class='ui-priority-secondary'>$icon $qty $label</span>";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "<p>" . implode(' ', $items) . "</p>";
|
||||||
|
}
|
||||||
|
|
||||||
public function ___processInput(WireInputData $input) {
|
public function ___processInput(WireInputData $input) {
|
||||||
|
|
||||||
|
if($this->useManager) return $this;
|
||||||
|
|
||||||
$n = 1;
|
$n = 1;
|
||||||
$names = array(
|
$names = array(
|
||||||
@@ -253,5 +329,27 @@ class InputfieldCommentsAdmin extends Inputfield implements InputfieldItemList {
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function ___getConfigInputfields() {
|
||||||
|
$modules = $this->wire()->modules;
|
||||||
|
$inputfields = parent::___getConfigInputfields();
|
||||||
|
|
||||||
|
/** @var InputfieldToggle $f */
|
||||||
|
$f = $modules->get('InputfieldToggle');
|
||||||
|
$f->attr('name', 'useManager');
|
||||||
|
$f->label = $this->_('Use comments manager rather than in-page editor?');
|
||||||
|
$f->description =
|
||||||
|
$this->_('When enabled user will be directed to the dedicated comments manager for editing comments.') . ' ' .
|
||||||
|
$this->_('This may be preferable because the comments manager has more features and uses pagination.');
|
||||||
|
$value = (int) $this->get('useManager');
|
||||||
|
$f->val($value);
|
||||||
|
$f->themeOffset = 1;
|
||||||
|
$inputfields->prepend($f);
|
||||||
|
if($value && !$this->commentsManagerUrl) {
|
||||||
|
$modules->getInstall('ProcessCommentsManager');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $inputfields;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -7,8 +7,10 @@ $(document).ready(function() {
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
$('.WireTabs').css('opacity', 1.0);
|
var $tabs = $('.WireTabs');
|
||||||
$('.WireTabs a.on').parent('li').click();
|
$tabs.css('opacity', 1.0);
|
||||||
|
$tabs.find('.uk-active').removeClass('uk-active');
|
||||||
|
$tabs.find('a.on').parent('li').click().addClass('uk-active');
|
||||||
|
|
||||||
$("a.CommentTextEdit").click(function() {
|
$("a.CommentTextEdit").click(function() {
|
||||||
var $textarea = $("<textarea></textarea>");
|
var $textarea = $("<textarea></textarea>");
|
||||||
|
@@ -1 +1 @@
|
|||||||
$(document).ready(function(){var ready=false;$(document).on("click",".WireTabs a",function($event){if(ready)window.location.href=$(this).attr("href");return false});$(".WireTabs").css("opacity",1);$(".WireTabs a.on").parent("li").click();$("a.CommentTextEdit").click(function(){var $textarea=$("<textarea></textarea>");var $parent=$(this).closest(".CommentTextEditable");$parent.parent(".CommentText").removeClass("CommentTextOverflow");$textarea.attr("name",$parent.attr("id"));$textarea.addClass($parent.attr("data-textarea-class"));$(this).remove();$textarea.val($parent.text());$parent.after($textarea);$parent.remove();return false});$(".CommentText").click(function(){$(this).find("a.CommentTextEdit").click();return false});$(".CommentItem").each(function(){var $item=$(this);var $table=$item.find(".CommentItemInfo");var height=$table.height()+30;var $text=$item.find(".CommentText");if($text.height()>height){$text.addClass("CommentTextOverflow")}});$("#CommentLimitSelect").change(function(){window.location="./?limit="+parseInt($(this).val())});$("#CommentListSort").change(function(){window.location="./?sort="+$(this).val()});function commentCheckboxClicked($checkbox){var $item=$checkbox.closest(".CommentItem");if($checkbox.is(":checked")){$item.addClass("CommentChecked")}else{$item.removeClass("CommentChecked")}}$(".CommentCheckbox").click(function(){commentCheckboxClicked($(this))});$("#CommentCheckAll").click(function(){var $items=$(".CommentCheckbox");if($(this).is(":checked")){$items.prop("checked",true)}else{$items.prop("checked",false)}$items.each(function(){commentCheckboxClicked($(this))})});$("#CommentActions").change(function(){var val=$(this).val();if(!val.length)return;var $checkedItems=$(".CommentChecked");if($checkedItems.length){$checkedItems.each(function(){if(val=="reset-upvotes"){$(this).find(".CommentUpvotes > input").val(0).change()}else if(val=="reset-downvotes"){$(this).find(".CommentDownvotes > input").val(0).change()}else{$(this).find(".CommentStatus > input[value='"+val+"']").click()}});$checkedItems.effect("highlight",500)}else{ProcessWire.alert($(this).attr("data-nochecked"))}$(this).val("")});$(document).on("change",".CommentItem :input",function(){var $this=$(this);if($this.is("[type='checkbox']"))return;$(this).closest(".CommentItem").addClass("CommentItemChanged")});$("#CommentListForm").submit(function(){$(this).addClass("CommentListFormSubmitted")});window.addEventListener("beforeunload",function(e){if($(".CommentListFormSubmitted").length)return;var $changes=$(".CommentItemChanged");if($changes.length==0)return;var msg=$("#CommentListForm").attr("data-unsaved");(e||window.event).returnValue=msg;return msg});var color=$(".WireTabs a.on").css("border-top-color");$("#CommentListHeader").css("border-top-color",color);ready=true});
|
$(document).ready(function(){var ready=false;$(document).on("click",".WireTabs a",function($event){if(ready)window.location.href=$(this).attr("href");return false});var $tabs=$(".WireTabs");$tabs.css("opacity",1);$tabs.find(".uk-active").removeClass("uk-active");$tabs.find("a.on").parent("li").click().addClass("uk-active");$("a.CommentTextEdit").click(function(){var $textarea=$("<textarea></textarea>");var $parent=$(this).closest(".CommentTextEditable");$parent.parent(".CommentText").removeClass("CommentTextOverflow");$textarea.attr("name",$parent.attr("id"));$textarea.addClass($parent.attr("data-textarea-class"));$(this).remove();$textarea.val($parent.text());$parent.after($textarea);$parent.remove();return false});$(".CommentText").click(function(){$(this).find("a.CommentTextEdit").click();return false});$(".CommentItem").each(function(){var $item=$(this);var $table=$item.find(".CommentItemInfo");var height=$table.height()+30;var $text=$item.find(".CommentText");if($text.height()>height){$text.addClass("CommentTextOverflow")}});$("#CommentLimitSelect").change(function(){window.location="./?limit="+parseInt($(this).val())});$("#CommentListSort").change(function(){window.location="./?sort="+$(this).val()});function commentCheckboxClicked($checkbox){var $item=$checkbox.closest(".CommentItem");if($checkbox.is(":checked")){$item.addClass("CommentChecked")}else{$item.removeClass("CommentChecked")}}$(".CommentCheckbox").click(function(){commentCheckboxClicked($(this))});$("#CommentCheckAll").click(function(){var $items=$(".CommentCheckbox");if($(this).is(":checked")){$items.prop("checked",true)}else{$items.prop("checked",false)}$items.each(function(){commentCheckboxClicked($(this))})});$("#CommentActions").change(function(){var val=$(this).val();if(!val.length)return;var $checkedItems=$(".CommentChecked");if($checkedItems.length){$checkedItems.each(function(){if(val=="reset-upvotes"){$(this).find(".CommentUpvotes > input").val(0).change()}else if(val=="reset-downvotes"){$(this).find(".CommentDownvotes > input").val(0).change()}else{$(this).find(".CommentStatus > input[value='"+val+"']").click()}});$checkedItems.effect("highlight",500)}else{ProcessWire.alert($(this).attr("data-nochecked"))}$(this).val("")});$(document).on("change",".CommentItem :input",function(){var $this=$(this);if($this.is("[type='checkbox']"))return;$(this).closest(".CommentItem").addClass("CommentItemChanged")});$("#CommentListForm").submit(function(){$(this).addClass("CommentListFormSubmitted")});window.addEventListener("beforeunload",function(e){if($(".CommentListFormSubmitted").length)return;var $changes=$(".CommentItemChanged");if($changes.length==0)return;var msg=$("#CommentListForm").attr("data-unsaved");(e||window.event).returnValue=msg;return msg});var color=$(".WireTabs a.on").css("border-top-color");$("#CommentListHeader").css("border-top-color",color);ready=true});
|
@@ -6,7 +6,7 @@
|
|||||||
* Manage all comments field data in chronological order.
|
* Manage all comments field data in chronological order.
|
||||||
*
|
*
|
||||||
* ProcessWire 3.x
|
* ProcessWire 3.x
|
||||||
* Copyright (C) 2019 by Ryan Cramer
|
* Copyright (C) 2022 by Ryan Cramer
|
||||||
* This file licensed under Mozilla Public License v2.0 http://mozilla.org/MPL/2.0/
|
* This file licensed under Mozilla Public License v2.0 http://mozilla.org/MPL/2.0/
|
||||||
*
|
*
|
||||||
* https://processwire.com
|
* https://processwire.com
|
||||||
@@ -23,7 +23,7 @@ class ProcessCommentsManager extends Process {
|
|||||||
return array(
|
return array(
|
||||||
'title' => __('Comments', __FILE__),
|
'title' => __('Comments', __FILE__),
|
||||||
'summary' => __('Manage comments in your site outside of the page editor.', __FILE__),
|
'summary' => __('Manage comments in your site outside of the page editor.', __FILE__),
|
||||||
'version' => 10,
|
'version' => 11,
|
||||||
'author' => 'Ryan Cramer',
|
'author' => 'Ryan Cramer',
|
||||||
'icon' => 'comments',
|
'icon' => 'comments',
|
||||||
'requires' => 'FieldtypeComments',
|
'requires' => 'FieldtypeComments',
|
||||||
@@ -104,7 +104,7 @@ class ProcessCommentsManager extends Process {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function init() {
|
public function init() {
|
||||||
$this->wire('modules')->get('FieldtypeComments');
|
$this->wire()->modules->get('FieldtypeComments');
|
||||||
parent::init();
|
parent::init();
|
||||||
$this->statuses = array(
|
$this->statuses = array(
|
||||||
Comment::statusFeatured => 'featured',
|
Comment::statusFeatured => 'featured',
|
||||||
@@ -152,19 +152,19 @@ class ProcessCommentsManager extends Process {
|
|||||||
return "<p>$error</p>";
|
return "<p>$error</p>";
|
||||||
}
|
}
|
||||||
|
|
||||||
$go = $this->wire('sanitizer')->pageName($this->wire('input')->get('go'));
|
$go = $this->wire()->sanitizer->pageName($this->wire('input')->get('go'));
|
||||||
|
|
||||||
if($count == 1 || $go) {
|
if($count == 1 || $go) {
|
||||||
$field = reset($fields);
|
$field = reset($fields);
|
||||||
$to = 'all';
|
$to = 'all';
|
||||||
if($go && in_array($go, $this->statuses)) $to = $go;
|
if($go && in_array($go, $this->statuses)) $to = $go;
|
||||||
$this->wire('session')->redirect("./list/$field->name/$to/");
|
$this->wire()->session->redirect("./list/$field->name/$to/");
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$out = "<h2>" . $this->_('Please select a comments field') . "</h2><ul>";
|
$out = "<h2>" . $this->_('Please select a comments field') . "</h2><ul>";
|
||||||
foreach($fields as $field) {
|
foreach($fields as $field) {
|
||||||
$out .= "<li><a href='./list/{$field->name}/pending/'>{$field->name}</a></li>";
|
$out .= "<li><a href='./list/$field->name/pending/'>$field->name</a></li>";
|
||||||
}
|
}
|
||||||
$out .= "</ul>";
|
$out .= "</ul>";
|
||||||
|
|
||||||
@@ -301,6 +301,107 @@ class ProcessCommentsManager extends Process {
|
|||||||
return $this->renderComments($comments);
|
return $this->renderComments($comments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the comment meta viewer/editor
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @since 3.0.203
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function ___executeMeta() {
|
||||||
|
$input = $this->wire()->input;
|
||||||
|
$commentId = (int) $input->get('comment_id');
|
||||||
|
$fieldId = (int) $input->get('field_id');
|
||||||
|
$pageId = (int) $input->get('page_id');
|
||||||
|
$modal = (int) $input->get('modal');
|
||||||
|
|
||||||
|
if($commentId < 1 || $fieldId < 1 || $pageId < 1) {
|
||||||
|
throw new WireException("Missing one of: comment_id, field_id, page_id");
|
||||||
|
}
|
||||||
|
|
||||||
|
$field = $this->wire()->fields->get($fieldId);
|
||||||
|
$fieldtype = $field->type; /** @var FieldtypeComments $fieldtype */
|
||||||
|
if(!$field || (!$fieldtype instanceof FieldtypeComments)) {
|
||||||
|
throw new WireException("Invalid field specified");
|
||||||
|
}
|
||||||
|
|
||||||
|
$page = $this->wire()->pages->get($pageId);
|
||||||
|
if(!$page->id || !$page->hasField($field) || !$page->editable($field)) {
|
||||||
|
throw new WireException("Invalid or non-editable page specified");
|
||||||
|
}
|
||||||
|
|
||||||
|
$comment = $fieldtype->getCommentByID($page, $field, $commentId);
|
||||||
|
if(!$comment) throw new WireException("Cannot find comment $commentId");
|
||||||
|
|
||||||
|
$meta = $comment->getMeta();
|
||||||
|
$flags = JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
|
||||||
|
if(defined('JSON_UNESCAPED_LINE_TERMINATORS')) $flags = $flags | JSON_UNESCAPED_LINE_TERMINATORS;
|
||||||
|
$metaJSON = empty($meta) ? '{ }' : json_encode($meta, $flags);
|
||||||
|
$numRows = substr_count($metaJSON, "\n")+1;
|
||||||
|
if($numRows < 10) $numRows = 10;
|
||||||
|
|
||||||
|
$this->headline(sprintf($this->_('Meta data for comment #%d'), $commentId));
|
||||||
|
if(empty($meta)) $this->message($this->_('Comment currently has no meta data'));
|
||||||
|
// $out = "<pre id='meta-preview'>$metaEncodedJSON</pre>";
|
||||||
|
|
||||||
|
$modules = $this->wire()->modules;
|
||||||
|
|
||||||
|
/** @var InputfieldForm $form */
|
||||||
|
$form = $modules->get('InputfieldForm');
|
||||||
|
$form->attr('method', 'post');
|
||||||
|
$form->attr('action', "./?comment_id=$commentId&page_id=$pageId&field_id=$fieldId&modal=$modal");
|
||||||
|
|
||||||
|
/** @var InputfieldTextarea $f */
|
||||||
|
$f = $modules->get('InputfieldTextarea');
|
||||||
|
$f->attr('name', 'meta');
|
||||||
|
$f->label = $this->_('Meta JSON editor');
|
||||||
|
$f->val($metaJSON);
|
||||||
|
$f->attr('rows', $numRows);
|
||||||
|
$f->attr('style', "font-family:monospace;");
|
||||||
|
$form->add($f);
|
||||||
|
|
||||||
|
/** @var InputfieldSubmit $f */
|
||||||
|
$f = $modules->get('InputfieldSubmit');
|
||||||
|
$f->attr('name', 'submit_save');
|
||||||
|
$f->val($this->_('Save changes'));
|
||||||
|
$form->add($f);
|
||||||
|
|
||||||
|
/** @var InputfieldSubmit $f */
|
||||||
|
$f = $modules->get('InputfieldButton');
|
||||||
|
$f->attr('name', 'submit_cancel');
|
||||||
|
$f->setSecondary(true);
|
||||||
|
$f->val($this->_('Cancel'));
|
||||||
|
$form->add($f);
|
||||||
|
|
||||||
|
if($input->post('submit_save')) {
|
||||||
|
$session = $this->wire()->session;
|
||||||
|
$form->processInput($input->post);
|
||||||
|
$metaInput = $form->getChildByName('meta');
|
||||||
|
$metaSaveJSON = $metaInput->val();
|
||||||
|
if($metaSaveJSON === $metaJSON) {
|
||||||
|
$this->message($this->_('No changes detected'));
|
||||||
|
$session->redirect($form->attr('action'));
|
||||||
|
} else {
|
||||||
|
$meta = json_decode($metaSaveJSON, true);
|
||||||
|
if(is_array($meta)) {
|
||||||
|
$result = $fieldtype->updateComment($page, $field, $comment, array('meta' => $meta));
|
||||||
|
if($result) {
|
||||||
|
$this->message(sprintf($this->_('Updated meta for comment #%d'), $commentId));
|
||||||
|
$session->redirect($form->attr('action'));
|
||||||
|
} else {
|
||||||
|
$this->error(sprintf($this->_('Error updating meata for comment #%d'), $commentId));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->error($this->_('Cannot save because invalid JSON'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$out = $form->render();
|
||||||
|
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process changes to posted comments
|
* Process changes to posted comments
|
||||||
*
|
*
|
||||||
@@ -485,7 +586,7 @@ class ProcessCommentsManager extends Process {
|
|||||||
$page = $comment->getPage();
|
$page = $comment->getPage();
|
||||||
$pageTitle = $sanitizer->entities1($page->get('title|name'));
|
$pageTitle = $sanitizer->entities1($page->get('title|name'));
|
||||||
$field = $comment->getField();
|
$field = $comment->getField();
|
||||||
$adminTheme = $this->wire('adminTheme');
|
$adminTheme = $this->wire()->adminTheme;
|
||||||
$isSuperuser = $this->user->isSuperuser();
|
$isSuperuser = $this->user->isSuperuser();
|
||||||
$allowDepth = $field->depth > 0;
|
$allowDepth = $field->depth > 0;
|
||||||
$allowDepthChange = $isSuperuser && $allowDepth;
|
$allowDepthChange = $isSuperuser && $allowDepth;
|
||||||
@@ -494,6 +595,10 @@ class ProcessCommentsManager extends Process {
|
|||||||
$numChildren = 0;
|
$numChildren = 0;
|
||||||
$text = $this->renderCommentText($comment);
|
$text = $this->renderCommentText($comment);
|
||||||
$id = $comment->id;
|
$id = $comment->id;
|
||||||
|
|
||||||
|
/** @var JqueryUI $jQueryUI */
|
||||||
|
$jQueryUI = $this->wire()->modules->get('JqueryUI');
|
||||||
|
$jQueryUI->use('modal');
|
||||||
|
|
||||||
$icons = array(
|
$icons = array(
|
||||||
'edit' => 'edit',
|
'edit' => 'edit',
|
||||||
@@ -528,6 +633,7 @@ class ProcessCommentsManager extends Process {
|
|||||||
$labels = array(
|
$labels = array(
|
||||||
'edit' => $this->_('edit'),
|
'edit' => $this->_('edit'),
|
||||||
'view' => $this->_('view'),
|
'view' => $this->_('view'),
|
||||||
|
'meta' => $this->_('meta'),
|
||||||
'page' => $this->_('Page'),
|
'page' => $this->_('Page'),
|
||||||
'date' => $this->_('When'),
|
'date' => $this->_('When'),
|
||||||
'status' => $this->_('Status'),
|
'status' => $this->_('Status'),
|
||||||
@@ -566,6 +672,7 @@ class ProcessCommentsManager extends Process {
|
|||||||
'siblings' => "../all/?pages_id=$page->id",
|
'siblings' => "../all/?pages_id=$page->id",
|
||||||
'pageView' => "$page->url#Comment$id",
|
'pageView' => "$page->url#Comment$id",
|
||||||
'pageEdit' => $page->editUrl(),
|
'pageEdit' => $page->editUrl(),
|
||||||
|
'metaEdit' => "../../../meta/?comment_id=$comment->id&page_id=$page->id&field_id=$field->id&modal=1",
|
||||||
'email' => "./?email=" . urlencode($values['email']),
|
'email' => "./?email=" . urlencode($values['email']),
|
||||||
'cite' => "../all/?cite=" . urlencode($values['cite']),
|
'cite' => "../all/?cite=" . urlencode($values['cite']),
|
||||||
'ip' => "../all/?ip=" . urlencode($values['ip']),
|
'ip' => "../all/?ip=" . urlencode($values['ip']),
|
||||||
@@ -707,6 +814,10 @@ class ProcessCommentsManager extends Process {
|
|||||||
foreach($outs as $out) if(!empty($out)) $numRows++;
|
foreach($outs as $out) if(!empty($out)) $numRows++;
|
||||||
$contentClass = 'CommentContent';
|
$contentClass = 'CommentContent';
|
||||||
if($numRows >= 7) $contentClass .= ' CommentContentLarge';
|
if($numRows >= 7) $contentClass .= ' CommentContentLarge';
|
||||||
|
|
||||||
|
$meta = $comment->getMeta();
|
||||||
|
$metaCnt = count($meta);
|
||||||
|
$metaTip = sprintf($this->_n('%d value', '%d values', $metaCnt), $metaCnt);
|
||||||
|
|
||||||
$out =
|
$out =
|
||||||
"<div class='CommentItem ui-helper-clearfix CommentItemStatus$comment->status'>" .
|
"<div class='CommentItem ui-helper-clearfix CommentItemStatus$comment->status'>" .
|
||||||
@@ -722,7 +833,9 @@ class ProcessCommentsManager extends Process {
|
|||||||
"<a href='$urls[siblings]' class='pw-tooltip' title='$tooltips[pageFilter]'><strong>$pageTitle</strong></a> " .
|
"<a href='$urls[siblings]' class='pw-tooltip' title='$tooltips[pageFilter]'><strong>$pageTitle</strong></a> " .
|
||||||
"<span class='detail'> " .
|
"<span class='detail'> " .
|
||||||
"<a class='detail' href='$urls[pageView]'>$labels[view]</a> / " .
|
"<a class='detail' href='$urls[pageView]'>$labels[view]</a> / " .
|
||||||
"<a class='detail' href='$urls[pageEdit]'>$labels[edit]</a>" .
|
"<a class='detail' href='$urls[pageEdit]'>$labels[edit]</a> / " .
|
||||||
|
"<a class='detail pw-tooltip pw-modal' title='$metaTip' href='$urls[metaEdit]' " .
|
||||||
|
"data-buttons='button' data-close='button[name=submit_cancel]'>$labels[meta]</a>" .
|
||||||
"</span>" .
|
"</span>" .
|
||||||
"<span class='CommentChangedIcon'>$icons[changed]</span>" .
|
"<span class='CommentChangedIcon'>$icons[changed]</span>" .
|
||||||
"</td>" .
|
"</td>" .
|
||||||
@@ -883,18 +996,23 @@ class ProcessCommentsManager extends Process {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected function renderComments(CommentArray $comments) {
|
protected function renderComments(CommentArray $comments) {
|
||||||
|
|
||||||
|
$input = $this->wire()->input;
|
||||||
|
|
||||||
$commentsBody = '';
|
$commentsBody = '';
|
||||||
$cnt = 0;
|
$cnt = 0;
|
||||||
$status = $this->input->urlSegment3;
|
$status = $input->urlSegment3;
|
||||||
$start = $comments->getStart();
|
$start = $comments->getStart();
|
||||||
$limit = $comments->getLimit();
|
$limit = $comments->getLimit();
|
||||||
$total = $comments->getTotal();
|
$total = $comments->getTotal();
|
||||||
$pageNumPrefix = $this->config->pageNumUrlPrefix;
|
$pageNumPrefix = $this->config->pageNumUrlPrefix;
|
||||||
$pageNum = $this->wire('input')->pageNum;
|
$pageNum = $input->pageNum();
|
||||||
$queryString = $this->getQueryString();
|
$queryString = $this->getQueryString();
|
||||||
$unsavedChangesLabel = $this->_('You have unsaved changes!');
|
$unsavedChangesLabel = $this->_('You have unsaved changes!');
|
||||||
$field = $comments->getField();
|
$field = $comments->getField();
|
||||||
|
$pagesId = (int) $input->get('pages_id');
|
||||||
|
|
||||||
|
if($pagesId) $this->breadcrumb("./$queryString", "Page $pagesId");
|
||||||
|
|
||||||
foreach($comments as $comment) {
|
foreach($comments as $comment) {
|
||||||
/** @var Comment $comment */
|
/** @var Comment $comment */
|
||||||
@@ -905,7 +1023,7 @@ class ProcessCommentsManager extends Process {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @var MarkupPagerNav $pager */
|
/** @var MarkupPagerNav $pager */
|
||||||
$pager = $this->wire('modules')->get('MarkupPagerNav');
|
$pager = $this->wire()->modules->get('MarkupPagerNav');
|
||||||
$pagerOut = $pager->render($comments, array(
|
$pagerOut = $pager->render($comments, array(
|
||||||
'queryString' => $queryString,
|
'queryString' => $queryString,
|
||||||
'baseUrl' => "./"
|
'baseUrl' => "./"
|
||||||
@@ -913,15 +1031,15 @@ class ProcessCommentsManager extends Process {
|
|||||||
/** @var JqueryWireTabs $wireTabs */
|
/** @var JqueryWireTabs $wireTabs */
|
||||||
$wireTabs = $this->modules->get('JqueryWireTabs');
|
$wireTabs = $this->modules->get('JqueryWireTabs');
|
||||||
$tabs = array();
|
$tabs = array();
|
||||||
$class = $this->input->urlSegment3 === 'all' ? 'on' : '';
|
$class = $input->urlSegment3 === 'all' ? 'on' : '';
|
||||||
$tabs["tabStatusAll"] = "<a class='$class' href='../all/'>" . $this->labelAll . "</a>";
|
$tabs["tabStatusAll"] = "<a class='$class' href='../all/$queryString'>" . $this->labelAll . "</a>";
|
||||||
|
|
||||||
foreach($this->statuses as $status => $name) {
|
foreach($this->statuses as $status => $name) {
|
||||||
if($status == Comment::statusDelete) continue;
|
if($status == Comment::statusDelete) continue;
|
||||||
$class = $this->input->urlSegment3 === $name ? 'on' : '';
|
$class = $input->urlSegment3 === $name ? 'on' : '';
|
||||||
$label = $this->statusTranslations[$status];
|
$label = $this->statusTranslations[$status];
|
||||||
if($label === $name) $label = ucfirst($label);
|
if($label === $name) $label = ucfirst($label);
|
||||||
$tabs["tabStatus$status"] = "<a class='$class' href='../$name/'>$label</a>";
|
$tabs["tabStatus$status"] = "<a class='$class' href='../$name/$queryString'>$label</a>";
|
||||||
}
|
}
|
||||||
|
|
||||||
$tabsOut = $wireTabs->renderTabList($tabs);
|
$tabsOut = $wireTabs->renderTabList($tabs);
|
||||||
@@ -936,7 +1054,7 @@ class ProcessCommentsManager extends Process {
|
|||||||
$button = $button->render();
|
$button = $button->render();
|
||||||
} else $button = '';
|
} else $button = '';
|
||||||
|
|
||||||
if($this->input->pageNum > 1) {
|
if($input->pageNum > 1) {
|
||||||
$queryString = "./$pageNumPrefix$pageNum$queryString";
|
$queryString = "./$pageNumPrefix$pageNum$queryString";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user