| Server IP : 5.129.245.98 / Your IP : 216.73.217.19 Web Server : Apache/2.4.66 (Debian) System : Linux 1b8c17c336b9 6.8.0-111-generic #111-Ubuntu SMP PREEMPT_DYNAMIC Sat Apr 11 23:16:02 UTC 2026 x86_64 User : www-data ( 33) PHP Version : 8.3.30 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : OFF | Perl : ON | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /var/www/html/wp-content/plugins/wpai-acf-add-on/src/fields/acf/repeater/ |
Upload File : |
<?php
namespace wpai_acf_add_on_pro\fields\acf\repeater;
use pmai_acf_add_on\ACFService;
use pmai_acf_add_on\fields\Field;
/**
* Class FieldRepeater
* @package pmai_acf_add_on\fields\acf\repeater
*/
class FieldRepeater extends Field {
/**
* Field type key
*/
public $type = 'repeater';
/**
* @var string
*/
public $mode = 'csv';
/**
* @var string
*/
public $delimiter = ',';
/**
* @var bool
*/
public $ignoreEmpties = false;
/**
* @var int
*/
public $rowIndex = 0;
/**
* @return string
*/
public function getMode() {
return $this->mode;
}
/**
* @param string $mode
*/
public function setMode($mode) {
$this->mode = $mode;
}
/**
* @return string
*/
public function getDelimiter() {
return $this->delimiter;
}
/**
* @param string $delimiter
*/
public function setDelimiter($delimiter) {
$this->delimiter = $delimiter;
}
/**
* @return string
*/
public function getRowIndex() {
return $this->rowIndex;
}
/**
* @param string $index
*/
public function setRowIndex($index) {
$this->rowIndex = $index;
}
/**
* @return boolean
*/
public function isIgnoreEmpties() {
return $this->ignoreEmpties;
}
/**
* @param boolean $ignoreEmpties
*/
public function setIgnoreEmpties($ignoreEmpties) {
$this->ignoreEmpties = $ignoreEmpties;
}
/**
*
* Parse field data
*
* @param $xpath
* @param $parsingData
* @param array $args
*/
public function parse($xpath, $parsingData, $args = array()) {
parent::parse($xpath, $parsingData, $args);
// Remove repeater row template.
if (isset($xpath['rows']['ROWNUMBER'])) {
unset($xpath['rows']['ROWNUMBER']);
}
if (!empty($xpath['rows'])) {
$values = array();
$is_ignore_empties = empty($xpath['is_ignore_empties']) ? false : true;
$this->setIgnoreEmpties($is_ignore_empties);
switch ($xpath['is_variable']){
case 'yes':
$rowFields = array_shift($xpath['rows']);
$this->setMode('xml');
for ($k = 0; $k < $this->getOption('count'); $k++) {
$repeaterXpath = '[' . ($k + 1) . ']/' . ltrim(trim($xpath['foreach'], '{}!'), '/');
$file = false;
$repeaterRows = \XmlImportParser::factory($this->parsingData['xml'], $this->getOption('base_xpath') . $repeaterXpath, "{.}", $file)->parse();
@unlink($file);
$xpath_suffix = '';
if ((!isset($rowFields[$this->getFieldKey()]) || (is_array($rowFields[$this->getFieldKey()]) || strpos($rowFields[$this->getFieldKey()], "!") !== 0)) && strpos($xpath['foreach'], "!") !== 0){
$xpath_suffix = $this->getOption('base_xpath') . $repeaterXpath;
$xpath_suffix = str_replace($parsingData['xpath_prefix'] . $parsingData['import']->xpath, '', $xpath_suffix);
}
$rowData = array();
/** @var Field $subField */
foreach ($this->getSubFields() as $subField){
$subField->parse($rowFields[$subField->getFieldKey()], $parsingData, array(
'field_path' => $this->getOption('field_path') . "[" . $this->getFieldKey() . "][rows][1]",
'xpath_suffix' => $xpath_suffix,
'repeater_count_rows' => count($repeaterRows),
'inside_repeater' => true
));
$rowData[$subField->getFieldKey()] = clone $subField;
}
$values[] = array(
'countRows' => count($repeaterRows),
'fields' => $rowData
);
}
break;
default:
switch ($xpath['is_variable']){
case 'csv':
$this->setDelimiter($xpath['separator']);
$this->setIgnoreEmpties(true);
break;
default:
$this->setDelimiter(false);
$this->setMode('fixed');
break;
}
foreach ($xpath['rows'] as $key => $rowFields) {
$rowData = array();
$subFields = $this->getSubFields();
/** @var Field $subField */
foreach ($subFields as $subField){
if (isset($rowFields[$subField->getFieldKey()])) {
$subField->parse($rowFields[$subField->getFieldKey()], $parsingData, array(
'field_path' => $this->getOption('field_path') . "[" . $this->getFieldKey() . "][rows][" . $key . "]",
'xpath_suffix' => empty($args['xpath_suffix']) ? '' : $args['xpath_suffix'],
'repeater_count_rows' => 0,
'inside_repeater' => true
));
$rowData[$subField->getFieldKey()] = clone $subField;
}
}
$values[] = $rowData;
}
break;
}
$this->setOption('values', $values);
}
}
/**
* @param $importData
* @param array $args
* @return mixed
*/
public function import($importData, $args = array()) {
$isUpdated = parent::import($importData, $args);
if (!$isUpdated){
return FALSE;
}
$values = $this->getOption('values');
$countRows = 0;
if (!empty($values)){
switch ($this->getMode()) {
case 'xml':
for ($k = 0; $k < $values[$this->getPostIndex()]['countRows']; $k++) {
$importData['i'] = $k;
// Init importData in all sub fields.
/** @var Field $subField */
foreach ($values[$this->getPostIndex()]['fields'] as $subFieldKey => $subField) {
$subField->importData = $importData;
}
if ($this->isImportRow($values[$this->getPostIndex()]['fields'])) {
/** @var Field $subField */
foreach ($values[$this->getPostIndex()]['fields'] as $subFieldKey => $subField) {
$subField->import($importData, array(
'container_name' => $this->getFieldName() . "_" . $countRows . "_"
));
}
$countRows++;
}
}
ACFService::update_post_meta($this, $this->getPostID(), $this->getFieldName(), $countRows);
break;
case 'csv':
$fields = array_shift($values);
if (!empty($fields)) {
// Init importData in all sub fields
/** @var Field $subField */
foreach ($fields as $subFieldKey => $subField) {
$subField->importData = $importData;
}
if ($this->isImportRow($fields)) {
$countRows = $this->getCountRows($fields);
for ($k = 0; $k < $countRows; $k++) {
$this->setRowIndex($k);
/** @var Field $subField */
foreach ($fields as $subFieldKey => $subField) {
$parentField = $subField->getParent();
if ($parentField) {
$parentField->setRowIndex($k);
}
$subField->import($importData, array(
'container_name' => $this->getFieldName() . "_" . $k . "_"
));
}
}
}
}
ACFService::update_post_meta($this, $this->getPostID(), $this->getFieldName(), $countRows);
break;
case 'fixed':
foreach ($values as $row_number => $fields) {
if (!empty($fields)) {
$countRows++;
// Init importData in all sub fields
/** @var Field $subField */
foreach ($fields as $subFieldKey => $subField) {
$subField->importData = $importData;
}
if ($this->isImportRow($fields)) {
/** @var Field $subField */
foreach ($fields as $subFieldKey => $subField) {
$subField->import($importData, array(
'container_name' => $this->getFieldName() . "_" . ($countRows - 1) . "_"
));
}
}
else {
$countRows--;
}
}
}
ACFService::update_post_meta($this, $this->getPostID(), $this->getFieldName(), $countRows);
break;
default:
break;
}
}
if ( apply_filters( 'pmxi_remove_old_acf_repeater_rows', true, $this->getPostID(), $this->getFieldName(), $countRows) && ( ! in_array( $this->getImportType(), ['import_users','shop_customer','taxonomies']))) {
// Remove old repeater rows from previous runs as they may not be removed when using some import settings.
global $wpdb;
$wpdb->query(
$wpdb->prepare(
"DELETE FROM {$wpdb->postmeta}
WHERE post_id = %d
AND (
(
meta_key LIKE %s
AND SUBSTRING_INDEX(SUBSTRING(meta_key, CHAR_LENGTH(%s) + 2), '_', 1) REGEXP '^[0-9]+$'
AND CAST(SUBSTRING_INDEX(SUBSTRING(meta_key, CHAR_LENGTH(%s) + 2), '_', 1) AS UNSIGNED) >= %d
)
OR
(
meta_key LIKE %s
AND SUBSTRING_INDEX(SUBSTRING(meta_key, CHAR_LENGTH(%s) + 3), '_', 1) REGEXP '^[0-9]+$'
AND CAST(SUBSTRING_INDEX(SUBSTRING(meta_key, CHAR_LENGTH(%s) + 3), '_', 1) AS UNSIGNED) >= %d
)
)",
$this->getPostID(),
str_replace('_','\\_', $this->getFieldName() . '_%'),
$this->getFieldName(),
$this->getFieldName(),
$countRows,
str_replace('_','\\_','_' . $this->getFieldName() . '_%'),
$this->getFieldName(),
$this->getFieldName(),
$countRows
)
);
}
}
/**
* @param $fields
* @return bool
*/
protected function isImportRow($fields){
$isImportRow = $this->isIgnoreEmpties() ? false : true;
if (!$isImportRow){
/** @var Field $field */
foreach ($fields as $field){
if ($field->isNotEmpty()){
$isImportRow = true;
break;
}
}
}
return $isImportRow;
}
/**
* @param $fields
* @return int
*/
protected function getCountRows($fields){
$countRows = 0;
$parentIndex = 0;
/** @var Field $field */
foreach ($fields as $field) {
$field->importData = $this->getImportData();
if ($field->getType() == 'repeater') {
$count = $field->getCountValues($parentIndex);
} else {
$count = $field->getCountValues();
}
if ($count > $countRows){
$countRows = $count;
}
}
return $countRows;
}
/**
* @param bool $parentIndex
*
* @return int
*/
public function getCountValues($parentIndex = false) {
$countRows = 0;
/** @var Field $field */
foreach ($this->getSubFields() as $field){
$field->importData = $this->getImportData();
$count = $field->getCountValues($parentIndex);
if ($count > $countRows){
$countRows = $count;
}
}
return $countRows;
}
/**
* @return bool
*/
public function getOriginalFieldValueAsString() {
return false;
}
}