mirror of
https://github.com/processwire/processwire.git
synced 2025-08-26 08:04:38 +02:00
Add support for export/import of comments fields (FieldtypeComments)
This commit is contained in:
@@ -758,6 +758,49 @@ function wireClassParents($className, $autoload = true) {
|
|||||||
return $a;
|
return $a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does given instance (or class) represent an instance of the given className (or class names)?
|
||||||
|
*
|
||||||
|
* @param object|string $instance Object instance to test (or string of its class name).
|
||||||
|
* @param string|array $className Class name or array of class names to test against.
|
||||||
|
* @param bool $autoload
|
||||||
|
* @return bool|string Returns one of the following:
|
||||||
|
* - boolean false if not an instance (whether $className argument is string or array).
|
||||||
|
* - boolean true if given a single $className (string) and $instance is an instance of it.
|
||||||
|
* - string of first matching class name if $className was an array of classes to test.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
function wireInstanceOf($instance, $className, $autoload = true) {
|
||||||
|
|
||||||
|
if(is_array($className)) {
|
||||||
|
$returnClass = true;
|
||||||
|
$classNames = $className;
|
||||||
|
} else {
|
||||||
|
$returnClass = false;
|
||||||
|
$classNames = array($className);
|
||||||
|
}
|
||||||
|
|
||||||
|
$matchClass = null;
|
||||||
|
$instanceParents = null;
|
||||||
|
|
||||||
|
foreach($classNames as $className) {
|
||||||
|
$className = wireClassName($className, true); // with namespace
|
||||||
|
if(is_object($instance) && class_exists($className, $autoload)) {
|
||||||
|
if($instance instanceof $className) $matchClass = $className;
|
||||||
|
} else {
|
||||||
|
if(is_null($instanceParents)) {
|
||||||
|
$instanceParents = wireClassParents($instance, $autoload);
|
||||||
|
$instanceClass = is_string($instance) ? $instance : wireClassName($instance, true);
|
||||||
|
$instanceParents[$instanceClass] = 1;
|
||||||
|
}
|
||||||
|
if(isset($parents[$className])) $matchClass = $className;
|
||||||
|
}
|
||||||
|
if($matchClass !== null) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $returnClass ? $matchClass : ($matchClass !== null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ProcessWire namespace aware version of PHP's is_callable() function
|
* ProcessWire namespace aware version of PHP's is_callable() function
|
||||||
*
|
*
|
||||||
|
@@ -755,12 +755,8 @@ class PagesExportImport extends Wire {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// fake-commit for more verbose testing of certain fieldtypes
|
// fake-commit for more verbose testing of certain fieldtypes
|
||||||
$fakeCommit = false;
|
$fakeCommitTypes = array('FieldtypePage', 'FieldtypeRepeater', 'FieldtypeComments');
|
||||||
if(!$options['commit']) {
|
$fakeCommit = $options['commit'] || wireInstanceOf($field->type, $fakeCommitTypes);
|
||||||
// we fake-commit Page refs so that validity is tested and errors known before commit
|
|
||||||
if($field->type instanceof FieldtypePage) $fakeCommit = true;
|
|
||||||
if($field->type instanceof FieldtypeRepeater) $fakeCommit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if($page->get('_importType') == 'create' && !$options['commit'] && !$fakeCommit) {
|
if($page->get('_importType') == 'create' && !$options['commit'] && !$fakeCommit) {
|
||||||
// test import on a new page, so value will always be used
|
// test import on a new page, so value will always be used
|
||||||
@@ -1141,11 +1137,14 @@ class PagesExportImport extends Wire {
|
|||||||
$exportable = true;
|
$exportable = true;
|
||||||
$reason = '';
|
$reason = '';
|
||||||
|
|
||||||
if($fieldtype instanceof FieldtypeFile) {
|
$extraType = wireInstanceOf($fieldtype, array(
|
||||||
// files are allowed
|
'FieldtypeFile',
|
||||||
|
'FieldtypeRepeater',
|
||||||
} else if($fieldtype instanceof FieldtypeRepeater) {
|
'FieldtypeComments',
|
||||||
// repeaters are allowed
|
));
|
||||||
|
|
||||||
|
if($extraType) {
|
||||||
|
// extra identified types are allowed
|
||||||
|
|
||||||
} else if($fieldtype instanceof FieldtypeFieldsetOpen || $fieldtype instanceof FieldtypeFieldsetClose) {
|
} else if($fieldtype instanceof FieldtypeFieldsetOpen || $fieldtype instanceof FieldtypeFieldsetClose) {
|
||||||
// fieldsets not exportable
|
// fieldsets not exportable
|
||||||
|
@@ -119,6 +119,14 @@ class Comment extends WireData {
|
|||||||
*/
|
*/
|
||||||
protected $_parent = null;
|
protected $_parent = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Quiet mode, when true actions like notification emails aren't triggered when applicable
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected $quiet = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a Comment and set defaults
|
* Construct a Comment and set defaults
|
||||||
*
|
*
|
||||||
@@ -375,6 +383,22 @@ class Comment extends WireData {
|
|||||||
return $comments->renderStars(false, $options);
|
return $comments->renderStars(false, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get or set quiet mode
|
||||||
|
*
|
||||||
|
* When quiet mode is active, comment additions/changes don't trigger notifications and such.
|
||||||
|
*
|
||||||
|
* @param bool $quiet Specify only if setting
|
||||||
|
* @return bool The current quiet mode
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function quiet($quiet = null) {
|
||||||
|
if(is_bool($quiet)) $this->quiet = $quiet;
|
||||||
|
return $this->quiet;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -246,6 +246,8 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected function checkExistingComment(Page $page, Field $field, Comment $comment) {
|
protected function checkExistingComment(Page $page, Field $field, Comment $comment) {
|
||||||
|
|
||||||
|
if($comment->quiet()) return;
|
||||||
|
|
||||||
$submitSpam = false;
|
$submitSpam = false;
|
||||||
$submitHam = false;
|
$submitHam = false;
|
||||||
@@ -312,7 +314,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
*/
|
*/
|
||||||
protected function checkNewComment(Page $page, Field $field, Comment $comment) {
|
protected function checkNewComment(Page $page, Field $field, Comment $comment) {
|
||||||
|
|
||||||
if($comment->id) return;
|
if($comment->id || $comment->quiet()) return;
|
||||||
|
|
||||||
$this->checkCommentCodes($comment);
|
$this->checkCommentCodes($comment);
|
||||||
|
|
||||||
@@ -1511,5 +1513,185 @@ class FieldtypeComments extends FieldtypeMulti {
|
|||||||
parent::___renamedField($field, $prevName);
|
parent::___renamedField($field, $prevName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export Comment to array
|
||||||
|
*
|
||||||
|
* @param Comment|array $comment
|
||||||
|
* @return array
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected function exportComment($comment) {
|
||||||
|
if(is_object($comment)) $comment = $comment->getArray();
|
||||||
|
if(isset($comment['created_users_id'])) {
|
||||||
|
$u = $this->wire('users')->get((int) $comment['created_users_id']);
|
||||||
|
$comment['created_user'] = $u->name;
|
||||||
|
unset($comment['created_users_id']);
|
||||||
|
}
|
||||||
|
return $comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export Comments to array
|
||||||
|
*
|
||||||
|
* @param CommentArray|array $comments
|
||||||
|
* @return array
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected function exportComments($comments) {
|
||||||
|
|
||||||
|
$commentsArray = array();
|
||||||
|
$exportComments = array();
|
||||||
|
|
||||||
|
foreach($comments as $comment) {
|
||||||
|
if($comment['status'] == Comment::statusSpam) continue; // don't export spam
|
||||||
|
$commentsArray[(int) $comment['id']] = $comment; // index by comment id
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($commentsArray as $id => $comment) {
|
||||||
|
|
||||||
|
$key = $this->getCommentExportKey($comment);
|
||||||
|
$comment = $this->exportComment($comment);
|
||||||
|
|
||||||
|
if(!empty($comment['parent_id'])) {
|
||||||
|
$parentID = (int) $comment['parent_id'];
|
||||||
|
$parent = isset($commentsArray[$parentID]) ? $commentsArray[$parentID] : null;
|
||||||
|
if($parent) $comment['parent_key'] = $this->getCommentExportKey($parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
$exportComments[$key] = $comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $exportComments;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get key used for exporting a comment
|
||||||
|
*
|
||||||
|
* @param Comment|array $comment
|
||||||
|
* @return string
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected function getCommentExportKey($comment) {
|
||||||
|
return "$comment[created] $comment[email]";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export value
|
||||||
|
*
|
||||||
|
* @param Page $page
|
||||||
|
* @param Field $field
|
||||||
|
* @param array|int|object|string $value
|
||||||
|
* @param array $options
|
||||||
|
* @return array|string
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function ___exportValue(Page $page, Field $field, $value, array $options = array()) {
|
||||||
|
$exportValue = array_values($this->exportComments($value));
|
||||||
|
return $exportValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import value
|
||||||
|
*
|
||||||
|
* Note: importValue does not delete comments, only insert or update.
|
||||||
|
*
|
||||||
|
* @param Page $page
|
||||||
|
* @param Field $field
|
||||||
|
* @param array $value
|
||||||
|
* @param array $options
|
||||||
|
* @return array|string
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function ___importValue(Page $page, Field $field, $value, array $options = array()) {
|
||||||
|
|
||||||
|
$value = $this->exportComments($value);
|
||||||
|
$comments = $page->get($field->name);
|
||||||
|
$commentsArray = array();
|
||||||
|
$addComments = array();
|
||||||
|
$updateComments = array();
|
||||||
|
$skipImportComments = array();
|
||||||
|
$updatePropertyCounts = array();
|
||||||
|
$skipUpdateProperties = array('id', 'created_user', 'created_users_id');
|
||||||
|
|
||||||
|
foreach($comments as $comment) {
|
||||||
|
if($comment->status == Comment::statusSpam) continue;
|
||||||
|
$key = $this->getCommentExportKey($comment);
|
||||||
|
$commentsArray[$key] = $comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($value as $key => $importCommentArray) {
|
||||||
|
|
||||||
|
if(!empty($importCommentArray['parent_key'])) {
|
||||||
|
$parentKey = $importCommentArray['parent_key'];
|
||||||
|
if(!isset($commentsArray[$parentKey])) {
|
||||||
|
$skipImportComments[$key] = $importCommentArray;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$importCommentArray['parent_id'] = $commentsArray[$parentKey]['id'];
|
||||||
|
unset($importCommentArray['parent_key']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!isset($commentsArray[$key])) {
|
||||||
|
$addComments[$key] = $importCommentArray;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$comment = $commentsArray[$key];
|
||||||
|
$commentArray = $this->exportComment($comment);
|
||||||
|
|
||||||
|
foreach($skipUpdateProperties as $property) {
|
||||||
|
unset($commentArray[$property]);
|
||||||
|
unset($importCommentArray[$property]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($commentArray == $importCommentArray) continue; // no changes
|
||||||
|
|
||||||
|
foreach($importCommentArray as $k => $v) {
|
||||||
|
if(isset($commentArray[$k]) && $commentArray[$k] == $v) continue;
|
||||||
|
$comment->set($k, $v);
|
||||||
|
$comment->quiet(true);
|
||||||
|
$updateComments[$key] = $comment;
|
||||||
|
if(!isset($updatePropertyCounts[$k])) $updatePropertyCounts[$k] = 0;
|
||||||
|
$updatePropertyCounts[$k]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($addComments as $commentArray) {
|
||||||
|
unset($commentArray['id']);
|
||||||
|
$u = $this->wire('users')->get("name=" . $this->wire('sanitizer')->pageName($commentArray['created_user']));
|
||||||
|
$commentArray['created_users_id'] = $u->id;
|
||||||
|
unset($commentArray['created_user']);
|
||||||
|
$comment = $this->makeComment($page, $field, $commentArray);
|
||||||
|
$comment->quiet(true);
|
||||||
|
$comments->add($comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
$numAddComments = count($addComments);
|
||||||
|
$numUpdateComments = count($updateComments);
|
||||||
|
$numSkipComments = count($skipImportComments);
|
||||||
|
|
||||||
|
if($numAddComments) {
|
||||||
|
$comments->message("$field->name: $numAddComments new added");
|
||||||
|
}
|
||||||
|
|
||||||
|
if($numUpdateComments) {
|
||||||
|
$counts = array();
|
||||||
|
foreach($updatePropertyCounts as $property => $count) {
|
||||||
|
$counts[] = "$property ($count)";
|
||||||
|
}
|
||||||
|
$comments->message("$field->name: $numUpdateComments updated - " . implode(', ', $counts));
|
||||||
|
$comments->trackChange('value');
|
||||||
|
}
|
||||||
|
|
||||||
|
if($numSkipComments) {
|
||||||
|
$comments->warning(
|
||||||
|
"$field->name: $numSkipComments skipped because parent comment(s) not yet present (run import again)"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $comments;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user