Control attributes

Hi!
Do you can add_filter to function get_attributes in /includes/components/class-attribute.php.
I want do dynamic form by my field.
My source:

		$form_args = hp\merge_arrays(
			$form_args,
			[
				'fields'  => [
					'private_pet' => [
						'label'    => 'Тип объявления',
						'description' => '',
						'type'     => 'select',
						'_order' => 1,
						'options'  => [
							'public'   => 'Объявление на продажу',
							'private'   => 'Мой личный питомец',
						],


						'attributes'      => [
							'data-render' => hivepress()->router->get_url( 'form_resource', [ 'form_name' => $form::get_meta( 'name' ) ] ),
						],
					],
				],
			]
		);

I want control fields by custom field.

Yes, you can try using the hivepress/v1/models/listing/attributes hook, but it doesn’t contain attribute values. You can also try the hivepress/v1/models/listing/fields hook, it contains an array of fields and the listing ID is already available. I recommend checking sample code snippets (search by the hook names) here Search · user:hivepress · GitHub

Thank you very match, Ihor!
This help.

I have problem dynamic form for listing_update.
In first create listing, data is save to /wp-json/hivepress/v1/forms/listing_submit/
But if edit form, url in form /wp-json/hivepress/v1/forms/listing_update/

If I change data-render for form - listing_update

'data-render' => hivepress()->router->get_url( 'listing_update_action', [ 'listing_id' => '1672'] ),

I get http-response 200, but I don’t get dynamic form in response(json).

Can you help me?)))
Thanks any thinks:)

I found answer:)
need fix url form

'data-render' => hivepress()->router->get_url( 'form_resource', [ 'form_name' => 'listing_submit'] ),

Все-таки этот хук не решает проблему полностью.
Для проверки конкретного поста, нужно получить id поста.
А его не получить, даже с get_query_var(‘hp_listing_id’), потому что
apply_filters( 'hivepress/v1/models/' . $model . '/attributes', $attributes )
используется в
add_action( 'init', [ $this, 'register_attributes' ], 100 );

А init срабатывает раньше чем роутинг.
В общем это проблема, и все-таки очень нехватает хука в функции get_attributes.

Думаю уже форк сделать(


Still, this hook does not completely solve the problem.
To check a specific post, you need to get the post id.
And you can’t get it, even with get_query_var(‘hp_listing_id’), because
apply_filters( 'hivepress/v1/models/' . $model . '/attributes', $attributes ) is used in
add_action( 'init', [ $this, 'register_attributes' ], 100 );

And init works before routing.
In general, this is a problem, and yet there is a very lacking hook in the get_attributes function.

I think to fork already (

Итог |Result

add_filter( 'hivepress/v1/models/listing/get_attributes', [ $this, 'my_pet_model_attributes' ], 10);
	
public function my_pet_model_attributes( $attributes ) {

		if(hp\is_rest() && isset($attributes['price']) && isset($_POST['listing_type']) && $_POST['listing_type'] == 1){
			unset($attributes['price']);
		}elseif(!hp\is_rest() && hivepress()->router->get_current_route_name() == 'listing_edit_page'){
			$meta = get_post_meta(get_query_var('hp_listing_id'), 'hp_listing_type', true);
			if($meta == 1){
				unset($attributes['price']);
			}
		}

		return $attributes;
	}

@ihor
Все-таки вариант, более предпочтителен.

'data-render' => hivepress()->router->get_url( 'form_resource', [ 'form_name' => $form::get_meta( 'name' ) ] ),

Но у него есть проблема, в controllers/class-attribute.php, есть ограничитель который не возращает форму для update или кого-нибудь других, кроме submit.

		if ( ! in_array( $model_name, hivepress()->attribute->get_models() ) || $form_name !== $model_name . '_submit' ) {
			return hp\rest_error( 400 );
		}

Вопрос, это критически важно(для безопасности например) или относительно?


Still, the option is more preferable.

 'data-render' => hivepress()->router->get_url( 'form_resource', [ 'form_name' => $form::get_meta( 'name' ) ] ),

But it has a problem, in controllers/class-attribute.php, there is a delimiter that doesn’t return the form for update or anything other than submit.

if ( ! in_array( $model_name, hivepress()->attribute->get_models() ) || $form_name !== $model_name . '_submit' ) {
return hp\rest_error( 400 );
}

The question is, is it critically important (for security, for example) or relatively?

Sorry, I can’t quite understand the required result but I’m sure that’s a workaround or a hack possible with the existing hooks. The initial form used for submitting listings is listing_submit, the editing one is listing_update. If I understand correctly you want to add the same Category drop-down to the editing form and refresh the form automatically if the Category is changed?

The attributes hook has no context so there are no listing details like ID, but the hivepress/v1/models/listing/fields one has the listing object as a 2nd parameter and it already has an ID there.

Приветствую, Игорь!
В общем да, но единственное мне нужно автоматически обновлять форму при изменении кастомного поля(не категории).

Я еще раз все пересмотрел, да Игорь, ты был прав, к полям можно подступиться через имеющие хуки. В частности hivepress/v1/models/listing/fields и hivepress/v1/forms/listing_update. Моя ошибка была, что приоритет в плагине у этих хуков 100, а у меня было 10, поэтому у меня еще не успели прогрузиться атрибуты :slight_smile:

Я добился всего того же что и через свой кастомный хук, единственная проблема которая осталась, что на этапе сохранения формы, он не сохраняет ее потому-что атрибут price не передается, хотя он на него и не ругается, просто как-будто происходит перезагрузка страницы и все, но если сделать без условий unset($fields['price']); в hivepress/v1/models/listing/fields то он все сохранит нормально.

Я предполагаю что не хватает условия на каком-то этапе, чтобы удалился атрибут, у тебя случаем нет никаких идей?:slight_smile:


Greetings, Igor!
In general, yes, but in the singular, I need to automatically sell the form to use a custom field (not a category).

I reviewed everything again, yes Igor, you were right, you can approach the fields through hook events. In particular, hivepress/v1/models/listing/fields and hivepress/v1/forms/listing_update. My mistake was that these hooks have a priority of 100, and I had 10, so I didn’t have time to load the attributes :slight_smile:

I achieved everything the same as through my custom hook, the only problem that remains is that at the stage of saving the form, it does not save it because the price attribute is not passed, although it does not swear at it, it’s just as if the page is reloaded and that’s all, but if you do without conditions unset($fields['price']); in hivepress/v1/models/listing/fields then it will save everything normally.

I’m assuming it’s missing a condition at some stage to remove the attribute, do you have any ideas? :slight_smile:


Мой код | My code

add_filter( 'hivepress/v1/forms/listing_update', [ $this, 'alter_update_form' ], 1000, 2 );
add_filter( 'hivepress/v1/models/listing/fields', [ $this, 'my_pet_model_fields' ], 1000,2);

public function alter_update_form( $form_args, $form ) {

		$fields = $form->get_model()->_get_fields();
		if($fields['listing_type']->get_value() == 1){
			unset($form_args['fields']['price']);
		}

		if (!hp\is_rest() && isset($_GET['listing_type']) && (int) $_GET['listing_type'] == 1){
			unset($form_args['fields']['price']);
		}

		if(hp\is_rest() && isset($form_args['fields']['price']) && isset($_POST['listing_type']) && $_POST['listing_type'] == 1){
			unset($form_args['fields']['price']);
		}

		if(!hp\is_rest() && isset($form_args['fields']['price']) && !is_null(hivepress()->request->get_context('listing')) && hivepress()->router->get_current_route_name() == 'listing_edit_page'){
			$meta = get_post_meta(hivepress()->request->get_context('listing')->get_id(), 'hp_listing_type', true);
			if($meta == 1){
				unset($form_args['fields']['price']);
			}
		} elseif (!hp\is_rest() && isset($form_args['fields']['price']) && !is_null(hivepress()->request->get_context('listing')) && hivepress()->router->get_current_route_name() == 'listing_submit_details_page'){
			$meta = get_post_meta(hivepress()->request->get_context('listing')->get_id(), 'hp_listing_type', true);
			if($meta == 1){
				unset($form_args['fields']['price']);
			}
		}

		$form_args = hp\merge_arrays(
			$form_args,
			[
				'fields'  => [
					'listing_type' => [
						'label'    => 'Тип объявления',
						'type'     => 'select',
						'_order' => 1,
						'default'   => isset($_GET['listing_type']) ? (int) $_GET['listing_type'] : 0,
						'attributes'      => [
							'data-render' => hivepress()->router->get_url( 'form_resource', [ 'form_name' => $form::get_meta( 'name' ) ] ),
						],
					],
				],
			]
		);

		return $form_args;
	}

public function my_pet_model_fields( $fields,$model ) {

		$model_fields = $model->_get_fields();
		if($model_fields['listing_type']->get_value() == 1){
			unset($fields['price']);
		}

		if (!hp\is_rest() && isset($_GET['listing_type']) && (int) $_GET['listing_type'] == 1){
			unset($fields['price']);
		}

		if(hp\is_rest() && isset($fields['price']) && isset($_POST['listing_type']) && $_POST['listing_type'] == 1){
			unset($fields['price']);
		}

		if(!hp\is_rest() && isset($fields['price']) && !is_null(hivepress()->request->get_context('listing')) && hivepress()->router->get_current_route_name() == 'listing_edit_page'){
			$meta = get_post_meta(hivepress()->request->get_context('listing')->get_id(), 'hp_listing_type', true);
			if($meta == 1){
				unset($fields['price']);
			}
		} elseif (!hp\is_rest() && isset($fields['price']) && !is_null(hivepress()->request->get_context('listing')) && hivepress()->router->get_current_route_name() == 'listing_submit_details_page'){
			$meta = get_post_meta(hivepress()->request->get_context('listing')->get_id(), 'hp_listing_type', true);
			if($meta == 1){
				unset($fields['price']);
			}
		}

		if(isset($fields['price'])){
			var_dump($model_fields);
		}


		return $fields;
	}

В общем проблема с валидацией

hivepress/v1/models/listing/fields

Не получает во время валидации в модель контекст со значениями, поэтому этот хук не отрабатывает как надо.
Можно попробовать сделать кастомный хук на валидации поля(там уже контекст полный со всеми значениями), но это очень большой костыль))
Будет у Вас возможность посмотреть и во время валидации добавить заполненное получение контекста на уровне hivepress/v1/models/listing/fields?


In general, the problem with verification

hivepress/v1/models/list/fields

It does not receive values ​​during the check in the context model, so this hook does not work as it should.
You can make a trial custom hook to check the field (there is already a full context with all values), but this is a very big crutch))
Do you have the option to look at and during validation add the Private context content at the hivepress/v1/models/listing/fields level?

Я если что сделал вот так | If I did something like this

add_filter( 'hivepress/v1/fields/price/required', [ $this, 'my_pet_price_required' ], 1000);
	public function my_pet_price_required($required){

		$listing = hivepress()->request->get_context( 'listing' );
		if(is_null($listing)){
			return $required;
		}

		$listing_type = $listing->_get_fields()['listing_type']->get_value();
		if(isset($listing_type) && (int) $listing_type === 1){
			 return false;
		}

		return $required;
	}

Sorry, I still can’t quite understand the required result but in any case, you can try this hook for adding custom validation errors Filter: hivepress/v1/models/{model_name}/errors | HivePress Hook Reference This way you can add any non-standard errors and the model object is passed to this hook.

Игорь, сейчас самая большая проблема в том, что очередь немного ограничивает возможность работы с контекстом:
1- Запускается валидация
2- Идет подгрузка полей (hivepress/v1/models/listing/fields)
3- Сохраняется контекст со значениями полей
4- Валидируются поля и значения контекста(модели)

То есть, я не могу влиять на поля на 2-ом этапе, по значению которые пришли из формы, потому что контекст еще не прогрузился, а данные в $_POST нулевые.
Поэтому тут мне кажется на правильной работы нужно добавить перед 4 шагом, еще раз получение полей для валидации, где уже будет доступен контекст со всем значениями.

Если ты посмотришь на функцию которую я добавил, ты я думаю поймешь зачем получать контекст перед валидацией.


Igor, now the biggest problem is that the queue slightly limits the ability to work with the context:
1- Run validation
2- Fields are loading (hivepress/v1/models/listing/fields)
3- Save context with field values
4- Fields and values ​​of the context (model) are validated

That is, I cannot influence the fields at the 2nd stage, by value that came from the form, because the context has not yet been loaded, and the data in $ _POST is null.
Therefore, here it seems to me that the correct work should be added before the 4th step, once again receiving the fields for validation, where the context with all the values ​​\u200b\u200bwill already be available.

If you look at the function I’ve added, you’ll understand why you need to get context before validation.

If possible explain the required functionality (e.g. showing/hiding fields depending on…) because at the moment I can’t quite understand the required result, I’d try to help then - there’s always a hook or a hacky solution that doesn’t require adding a new hook, we tried to make the hooks API as versatile as possible.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.