下面是一种在ACF字段中键入值时实现验证的方法,将代码放在主题函数中。php或为其创建插件:您需要将$fieldName、$fieldKey属性值更改为字段的正确值--they are the field name and field key of the same field we are validating--
class MyPrefix_MetaFieldValidation
{
protected static $instance;
protected $fieldName = \'original-title-mcpedl\'; // <- Change this with the ACF field name
protected $fieldKey = \'field_61abaa164244a\'; // <- Change this with the field key
protected $ajaxAction = \'myprefix_validate_title\';
protected function __construct()
{
}
public function run()
{
add_filter(\'acf/validate_value/key=\' . $this->fieldKey, [$this, \'acfValidation\'], 10, 2);
add_action(\'wp_ajax_\' . $this->ajaxAction, [$this, \'ajaxValidation\']);
add_action(\'admin_footer\', [$this, \'ajaxValidationJS\']);
}
/**
* Print the Validation JS on the post edit screen.
*/
public function ajaxValidationJS()
{
if(! $this->isPostEditScreen()) {
return;
}
$nonce = wp_create_nonce($this->ajaxAction);
?>
<script>
jQuery(document).ready(function(){
jQuery(\'#acf-<?= $this->fieldKey; ?>\').on(\'keyup\', function (){
var field = jQuery(this);
var value = field.val();
if(! value) {
return;
}
var post_id = jQuery(\'#post_ID\').val();
var formatError = function(msg) {
return \'<div class="acf-notice -error acf-error-message"><p>\' + msg + \'</p></div>\';
}
jQuery.ajax({
url: ajaxurl,
data: {"action": "<?= $this->ajaxAction; ?>", "nonce" : "<?= $nonce; ?>", "post_id" : post_id, "meta_value" : value },
type: "POST",
complete : function(response) {
var json = response.responseJSON;
field.parents(\'.acf-input\').find(\'.acf-notice\').remove();
if(response.status != 200) {
field.parents(\'.acf-input\').prepend(formatError(\'Network or server error!\'));
return;
}
if(! json.valid) {
field.parents(\'.acf-input\').prepend(formatError(json.msg));
}
}
});
});
});
</script>
<?php
}
/**
* Perform the ajax validation on the meta field
*/
public function ajaxValidation()
{
$postId = $_REQUEST[\'post_id\'] ? intval($_REQUEST) : 0;
$metaValue = $_REQUEST[\'meta_value\'] ? $_REQUEST[\'meta_value\'] : \'\';
$nonce = $_REQUEST[\'nonce\'] ? $_REQUEST[\'nonce\'] : \'\';
if(! wp_verify_nonce($nonce, $this->ajaxAction)) {
$this->ajaxResponse([
\'valid\' => false,
\'msg\' => \'Invalid nonce supplied\'
]);
}
if(! $metaValue) {
$this->ajaxResponse([
\'valid\' => true,
\'msg\' => \'Empty value\'
]);
}
$existingTitle = $this->metaValueExists($this->fieldName, $metaValue, $postId);
if($existingTitle) {
$this->ajaxResponse([
\'valid\' => false,
\'msg\' => \'This title is already exists for the post id \' . $existingTitle->post_id,
]);
}
$this->ajaxResponse([
\'valid\' => true,
\'msg\' => \'\',
]);
}
public function acfValidation($valid, $value)
{
if(empty($value)) {
return $valid;
}
$postId = isset($_POST[\'post_id\']) ? intval($_POST[\'post_id\']) : null;
$existingTitle = $this->metaValueExists($this->fieldName, $value, $postId);
if($existingTitle) {
$valid = \'This title is already exists for the post id \' . $existingTitle->post_id;
}
return $valid;
}
/**
* Create an ajax response
* @param array $data
*/
protected function ajaxResponse($data)
{
header(\'Content-Type: application/json;charset=UTF-8\');
echo json_encode($data);
exit;
}
/**
* Check if we are on the post editing screen
* @return bool
*/
protected function isPostEditScreen()
{
global $pagenow;
return (is_admin() && (\'post.php\' === $pagenow || \'post-new.php\' === $pagenow));
}
/**
* Check if a given meta value is already in the database
* @param string $metaKey
* @param string $metaValue
* @param null|int $currentPostId
* @return false|object
*/
protected function metaValueExists($metaKey, $metaValue, $currentPostId = null) {
// Return early if the supplied meta key or value is empty
$metaValue = trim($metaValue);
if (empty($metaKey) || empty($metaValue)) {
return false;
}
// Ensure that the supplied post id is integer
$currentPostId = intval($currentPostId);
// Query the wp_postmeta table for the meta value and meta key
global $wpdb;
$query = "SELECT * FROM $wpdb->postmeta WHERE meta_key LIKE \'%s\' AND meta_value LIKE \'%s\'";
// Exclude the current post id only if it is not empty
if($currentPostId) {
$query .= " AND post_id != $currentPostId";
}
$result = $wpdb->get_row($wpdb->prepare($query, $metaKey, $metaValue));
// Return the database row object or false if no record found
return ($result) ?: false;
}
public static function getInstance()
{
if(! static::$instance) {
static::$instance = new static();
}
return static::$instance;
}
}
// Run our plugin
MyPrefix_MetaFieldValidation::getInstance()->run();
下面是我们在前面的代码中所做的操作:
我将所有代码放在一个单独的类中“;MyPrefix\\u MetaFieldValidation“;
我稍微修改了您在问题中输入的代码,以便验证方法;元值存在”;与在上运行的方法分离;acf/validate\\u value“;,因为我们需要在另一个地方使用它。
此外,我将负责从数据库中获取重复记录的查询更改为更轻量级的查询。
我删除了保存帖子id的隐藏自定义字段的使用,因为已经有一个字段保存当前帖子id。
我创建了一个新的管理ajax操作“;ajaxValidation“;它使用验证方法并以JSON结果响应。
每当用户在自定义字段中键入要验证的值时,JS代码使用jQuery创建ajax请求,如果键入的值重复,则显示错误。
Note:此代码仅在自定义字段中插入值时向用户显示错误,但不会阻止用户将帖子保存为草稿。