mirror of
https://github.com/processwire/processwire.git
synced 2025-08-25 07:41:30 +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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
|
@@ -755,12 +755,8 @@ class PagesExportImport extends Wire {
|
||||
);
|
||||
|
||||
// fake-commit for more verbose testing of certain fieldtypes
|
||||
$fakeCommit = false;
|
||||
if(!$options['commit']) {
|
||||
// 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;
|
||||
}
|
||||
$fakeCommitTypes = array('FieldtypePage', 'FieldtypeRepeater', 'FieldtypeComments');
|
||||
$fakeCommit = $options['commit'] || wireInstanceOf($field->type, $fakeCommitTypes);
|
||||
|
||||
if($page->get('_importType') == 'create' && !$options['commit'] && !$fakeCommit) {
|
||||
// test import on a new page, so value will always be used
|
||||
@@ -1141,11 +1137,14 @@ class PagesExportImport extends Wire {
|
||||
$exportable = true;
|
||||
$reason = '';
|
||||
|
||||
if($fieldtype instanceof FieldtypeFile) {
|
||||
// files are allowed
|
||||
|
||||
} else if($fieldtype instanceof FieldtypeRepeater) {
|
||||
// repeaters are allowed
|
||||
$extraType = wireInstanceOf($fieldtype, array(
|
||||
'FieldtypeFile',
|
||||
'FieldtypeRepeater',
|
||||
'FieldtypeComments',
|
||||
));
|
||||
|
||||
if($extraType) {
|
||||
// extra identified types are allowed
|
||||
|
||||
} else if($fieldtype instanceof FieldtypeFieldsetOpen || $fieldtype instanceof FieldtypeFieldsetClose) {
|
||||
// fieldsets not exportable
|
||||
|
@@ -119,6 +119,14 @@ class Comment extends WireData {
|
||||
*/
|
||||
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
|
||||
*
|
||||
@@ -375,6 +383,22 @@ class Comment extends WireData {
|
||||
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) {
|
||||
|
||||
if($comment->quiet()) return;
|
||||
|
||||
$submitSpam = false;
|
||||
$submitHam = false;
|
||||
@@ -312,7 +314,7 @@ class FieldtypeComments extends FieldtypeMulti {
|
||||
*/
|
||||
protected function checkNewComment(Page $page, Field $field, Comment $comment) {
|
||||
|
||||
if($comment->id) return;
|
||||
if($comment->id || $comment->quiet()) return;
|
||||
|
||||
$this->checkCommentCodes($comment);
|
||||
|
||||
@@ -1511,5 +1513,185 @@ class FieldtypeComments extends FieldtypeMulti {
|
||||
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