shop_template_repository = $shop_template_repository;
$this->attribute_template_repository = $attribute_template_repository;
$this->detail_template_repository = $detail_template_repository;
$this->key_generator = $key_generator;
}
/**
* @hook init
* @since 0.9
*/
public function render()
{
do_action('aff_admin_meta_box_before_render_product_container');
$shop_templates = $this->shop_template_repository->find_all();
$attribute_templates = $this->attribute_template_repository->find_all();
$detail_templates = $this->detail_template_repository->find_all();
$container = Carbon_Container::make('post_meta', __('Affilicious Product', 'affilicious'))
->show_on_post_type(Product::POST_TYPE)
->set_priority('core')
->add_tab(__('General', 'affilicious'), $this->get_general_fields())
->add_tab(__('Variants', 'affilicious'), $this->get_variants_fields($attribute_templates, $shop_templates))
->add_tab(__('Shops', 'affilicious'), $this->get_shops_fields($shop_templates))
->add_tab(__('Details', 'affilicious'), $this->get_details_fields($detail_templates))
->add_tab(__('Review', 'affilicious'), $this->get_review_fields())
->add_tab(__('Relations', 'affilicious'), $this->get_relations_fields());
$container = apply_filters('aff_admin_meta_box_render_product_container', $container);
do_action('aff_admin_meta_box_after_render_product_container', $container);
}
/**
* Get the general fields
*
* @since 0.9
* @return array
*/
protected function get_general_fields()
{
$fields = array(
Carbon_Field::make('select', Carbon_Product_Repository::TYPE, __('Type', 'affilicious'))
->add_options(array(
'simple' => __('Simple', 'affilicious'),
'complex' => __('Complex', 'affilicious'),
)),
Carbon_Field::make('tags', Carbon_Product_Repository::TAGS, __('Tags', 'affilicious'))
->set_max_items(self::TAGS_LIMIT)
->set_help_text(__('Custom product tags like "test winner" or "best price".', 'affilicious'))
->set_conditional_logic(array(
'relation' => 'and',
array(
'field' => Carbon_Product_Repository::TYPE,
'value' => 'complex',
'compare' => '!=',
)
)),
);
return apply_filters('aff_admin_meta_box_render_product_container_general_fields', $fields);
}
/**
* Get the variants fields
*
* @since 0.9
* @param Attribute_Template[] $attribute_templates
* @param Shop_Template[] $shop_templates
* @return array
*/
protected function get_variants_fields($attribute_templates, $shop_templates)
{
$fields = array();
if(empty($attribute_templates)) {
$fields[] = $this->get_variants_empty_attributes_notice_field();
return $fields;
}
$tags = [];
foreach ($attribute_templates as $attribute_template) {
if($attribute_template->has_id()) {
$tags[$attribute_template->get_id()->get_value()] = $attribute_template->get_name()->get_value();
}
}
$conditions = array('relation' => 'or');
foreach ($attribute_templates as $attribute_template) {
$conditions[] = array(
'field' => Carbon_Product_Repository::ENABLED_ATTRIBUTES,
'value' => $attribute_template->get_id()->get_value(),
'compare' => 'CONTAINS',
);
}
$fields[] = Carbon_Field::make('tags', Carbon_Product_Repository::ENABLED_ATTRIBUTES, __('Enabled Attributes', 'affilicious'))
->add_tags($tags)
->set_max_items(self::ENABLED_ATTRIBUTES_LIMIT)
->set_help_text(sprintf(
__('Add the names of some attribute templates to attach them to the product variants.', 'affilicious'),
admin_url('edit-tags.php?taxonomy=aff_attribute_tmpl&post_type=aff_product')
));
$fields[] = Carbon_Field::make('complex', Carbon_Product_Repository::VARIANTS, __('Variants', 'affilicious'))
->set_max(self::VARIANTS_LIMIT)
->setup_labels(array(
'plural_name' => __('Variants', 'affilicious'),
'singular_name' => __('Variant', 'affilicious'),
))
->add_fields($this->get_variant_field($attribute_templates, $shop_templates))
->set_header_template('
<# if (' . Carbon_Product_Repository::VARIANT_NAME . ') { #>
{{ ' . Carbon_Product_Repository::VARIANT_NAME . ' }}
<# } #>
')
->set_conditional_logic($conditions);
return apply_filters('aff_admin_meta_box_render_product_container_variants_fields', $fields);
}
/**
* Get a single variant field.
*
* @since 0.9
* @param Attribute_Template[] $attribute_templates
* @param Shop_Template[] $shop_templates
* @return \Carbon_Fields\Field[]
*/
public function get_variant_field($attribute_templates, $shop_templates)
{
$field = array_merge(array(
Carbon_Field::make('hidden', Carbon_Product_Repository::VARIANT_ID),
Carbon_Field::make('hidden', Carbon_Product_Repository::VARIANT_ENABLED_ATTRIBUTES),
Carbon_Field::make('text', Carbon_Product_Repository::VARIANT_NAME, __('Name', 'affilicious'))
->set_required(true)
->set_width(70),
Carbon_Field::make('checkbox', Carbon_Product_Repository::VARIANT_DEFAULT, __('Default Variant', 'affilicious'))
->set_option_value('yes')
->help_text(__('This variant will be shown as default for the parent product.', 'affilicious'))
->set_width(30),
),
$this->get_variants_attribute_fields($attribute_templates),
array(
Carbon_Field::make('tags', Carbon_Product_Repository::VARIANT_TAGS, __('Tags', 'affilicious'))
->set_max_items(self::TAGS_LIMIT)
->set_help_text(__('Custom product tags like "test winner" or "best price".', 'affilicious')),
Carbon_Field::make('image', Carbon_Product_Repository::VARIANT_THUMBNAIL_ID, __('Thumbnail', 'affilicious')),
Carbon_Field::make('image_gallery', Carbon_Product_Repository::VARIANT_IMAGE_GALLERY, __('Image Gallery', 'affilicious')),
!empty($shop_templates) ? $this->get_shop_tabs(Carbon_Product_Repository::VARIANT_SHOPS, __('Shops', 'affilicious'), $shop_templates) : $this->get_shops_empty_notice_field(),
)
);
return $field;
}
/**
* Get the attribute fields for the variants.
*
* @since 0.9
* @param Attribute_Template[] $attribute_templates
* @return array
*/
public function get_variants_attribute_fields($attribute_templates)
{
$fields = array();
foreach ($attribute_templates as $attribute_template) {
$fields[] = $this->get_variants_attribute_field($attribute_template);
}
return $fields;
}
/**
* Get a single attribute field for the variants.
*
* @since 0.9
* @param Attribute_Template $attribute_template
* @return mixed
*/
public function get_variants_attribute_field(Attribute_Template $attribute_template)
{
// Build the key
$attribute_key = $this->key_generator->generate_from_slug($attribute_template->get_slug());
$field_key = sprintf(Carbon_Product_Repository::VARIANT_ATTRIBUTE_VALUE, $attribute_key->get_value());
// Build the name
$field_name = trim(sprintf('%s %s', $attribute_template->get_name(), $attribute_template->get_unit()));
// Build the type
$field_type = $attribute_template->get_type()->get_value();
$field = Carbon_Field::make($field_type, $field_key, $field_name)->set_required(true)
->set_required(true)
->set_conditional_logic(array(
'relation' => 'and',
array(
'field' => Carbon_Product_Repository::VARIANT_ENABLED_ATTRIBUTES,
'value' => $attribute_template->get_id()->get_value(),
'compare' => 'CONTAINS',
)
));
return $field;
}
/**
* Get the empty attributes notice for the variants.
*
* @since 0.9
* @return Carbon_Field
*/
public function get_variants_empty_attributes_notice_field()
{
$notice = Template_Helper::stringify('notices/warning-notice', array(
'message' => sprintf(
__('No attribute templates available! Please create one here.', 'affilicious'),
admin_url('edit-tags.php?taxonomy=aff_attribute_tmpl&post_type=aff_product')
)
));
$field = Carbon_Field::make('html', 'affilicious_product_no_attributes')->set_html($notice);
return $field;
}
/**
* Get the shops fields
*
* @since 0.9
* @param Shop_Template[] $shop_templates
* @return array
*/
protected function get_shops_fields($shop_templates)
{
$fields = array();
if(empty($shop_templates)) {
$fields[] = $this->get_shops_empty_notice_field();
return $fields;
}
$fields[] = $this->get_shop_tabs(Carbon_Product_Repository::SHOPS, __('Shops', 'affilicious'), $shop_templates);
return apply_filters('aff_admin_meta_box_render_product_container_shops_fields', $fields);
}
/**
* Get the empty notice for the shops.
*
* @since 0.9
* @return Carbon_Field
*/
protected function get_shops_empty_notice_field()
{
$notice = $notice = Template_Helper::stringify('notices/warning-notice', array(
'message' => sprintf(
__('No shop templates available! Please create one here.', 'affilicious'),
admin_url('edit-tags.php?taxonomy=aff_shop_tmpl&post_type=aff_product')
)
));
$fields = Carbon_Field::make('html', 'affilicious_product_no_shops')->set_html($notice);
return $fields;
}
/**
* Get the shops tabs
*
* @since 0.9
* @param string $name
* @param null|string $label
* @param Shop_Template[] $shop_templates
* @return Carbon_Complex_Field
*/
protected function get_shop_tabs($name, $label = null, $shop_templates)
{
/** @var Carbon_Complex_Field $tabs */
$tabs = Carbon_Field::make('complex', $name, $label)
->set_layout('tabbed-horizontal')
->set_max(self::SHOP_LIMIT)
->setup_labels(array(
'plural_name' => __('Shops', 'affilicious'),
'singular_name' => __('Shop', 'affilicious'),
));
foreach ($shop_templates as $shop_template) {
$fields = array(
Carbon_Field::make('hidden', Carbon_Product_Repository::SHOP_TEMPLATE_ID, __('Shop Template ID', 'affilicious'))
->set_required(true)
->set_value($shop_template->get_id()->get_value()),
Carbon_Field::make('text', Carbon_Product_Repository::SHOP_AFFILIATE_LINK, __('Affiliate Link', 'affilicious'))
->set_required(true),
Carbon_Field::make('text', Carbon_Product_Repository::SHOP_AFFILIATE_PRODUCT_ID, __('Affiliate Product ID', 'affilicious'))
->set_help_text(__('Unique Product ID like Amazon ASIN, Affilinet ID, Ebay ID and etc.', 'affilicious')),
Carbon_Field::make('select', Carbon_Product_Repository::SHOP_AVAILABILITY, __('Availability', 'affilicious'))
->set_required(true)
->add_options(array(
'available' => __('Available', 'affilicious'),
'out-of-stock' => __('Out Of Stock', 'affilicious'),
)),
Carbon_Field::make('text', Carbon_Product_Repository::SHOP_PRICE, __('Price', 'affilicious'))
->set_width(50),
Carbon_Field::make('text', Carbon_Product_Repository::SHOP_OLD_PRICE, __('Old Price', 'affilicious'))
->set_width(50),
Carbon_Field::make('select', Carbon_Product_Repository::SHOP_CURRENCY, __('Currency', 'affilicious'))
->set_required(true)
->add_options(Currency::labels()),
Carbon_Field::make('hidden', Carbon_Product_Repository::SHOP_UPDATED_AT, __('Updated At', 'affilicious'))
->set_default_value(current_time('timestamp'))
->set_required(true)
);
$tabs->add_fields($this->key_generator->generate_from_slug($shop_template->get_slug())->get_value(), $shop_template->get_name()->get_value(), $fields);
}
return $tabs;
}
/**
* Get the details fields.
*
* @since 0.9
* @param Detail_Template[] $detail_templates
* @return array
*/
protected function get_details_fields($detail_templates)
{
$fields = array();
if(empty($detail_templates)) {
$fields[] = $this->get_details_empty_notice_field();
return $fields;
}
$tags = [];
foreach ($detail_templates as $detail_template) {
if($detail_template->has_id()) {
$tags[$detail_template->get_id()->get_value()] = $detail_template->get_name()->get_value();
}
}
$fields[] = Carbon_Field::make('tags', Carbon_Product_Repository::ENABLED_DETAILS, __('Enabled Details', 'affilicious'))
->add_class('aff_details')
->set_max_items(self::ENABLED_DETAILS_LIMIT)
->add_tags($tags)
->set_help_text(sprintf(
__('Add the names of some detail templates to attach them to the product.', 'affilicious'),
admin_url('edit-tags.php?taxonomy=aff_detail_tmpl&post_type=aff_product')
));
foreach ($detail_templates as $detail_template) {
$fields[] = $this->get_detail_field($detail_template);
}
return apply_filters('aff_admin_meta_box_render_product_container_details_fields', $fields);
}
/**
* Get a single detail field.
*
* @since 0.9
* @param Detail_Template $detail_template
* @return Carbon_Field\
*/
protected function get_detail_field(Detail_Template $detail_template)
{
// Build the key
$detail_key = $this->key_generator->generate_from_slug($detail_template->get_slug());
$field_key = sprintf(Carbon_Product_Repository::DETAIL_VALUE, $detail_key);
// Build the name
$field_name = trim(sprintf('%s %s', $detail_template->get_name(), $detail_template->get_unit()));
// Build the type
$detail_type = $detail_template->get_type();
$field_type = !$detail_type->is_boolean() ? $detail_type->get_value() : 'select';
$field = Carbon_Field::make($field_type, $field_key, $field_name)
->set_conditional_logic(array(
'relation' => 'and',
array(
'field' => Carbon_Product_Repository::ENABLED_DETAILS,
'value' => $detail_template->get_id()->get_value(),
'compare' => 'CONTAINS',
)
));
if($detail_type->is_boolean()) {
$field->add_options(array(
'yes' => __('Yes', 'affilicious'),
'no' => __('No', 'affilicious'),
));
}
return $field;
}
/**
* Get the empty notice field for thr details.
*
* @since 0.9
* @return Carbon_Field
*/
protected function get_details_empty_notice_field()
{
$notice = Template_Helper::stringify('notices/warning-notice', [
'message' => sprintf(
__('No detail templates available! Please create one here.', 'affilicious'),
admin_url('edit-tags.php?taxonomy=aff_detail_tmpl&post_type=aff_product')
)
]);
$field = Carbon_Field::make('html', 'affilicious_product_no_detail_templates')->set_html($notice);
return $field;
}
/**
* Get the review fields
*
* @since 0.9
* @return array
*/
protected function get_review_fields()
{
$fields = array(
Carbon_Field::make('select', Carbon_Product_Repository::REVIEW_RATING, __('Rating', 'affilicious'))
->add_options(array(
'none' => sprintf(__('None', 'affilicious'), 0),
'0' => sprintf(__('%s stars', 'affilicious'), 0),
'0.5' => sprintf(__('%s stars', 'affilicious'), 0.5),
'1' => sprintf(__('%s star', 'affilicious'), 1),
'1.5' => sprintf(__('%s stars', 'affilicious'), 1.5),
'2' => sprintf(__('%s stars', 'affilicious'), 2),
'2.5' => sprintf(__('%s stars', 'affilicious'), 2.5),
'3' => sprintf(__('%s stars', 'affilicious'), 3),
'3.5' => sprintf(__('%s stars', 'affilicious'), 3.5),
'4' => sprintf(__('%s stars', 'affilicious'), 4),
'4.5' => sprintf(__('%s stars', 'affilicious'), 4.5),
'5' => sprintf(__('%s stars', 'affilicious'), 5),
)),
Carbon_Field::make('number', Carbon_Product_Repository::REVIEW_VOTES, __('Votes', 'affilicious'))
->set_help_text(__('If you want to hide the votes, just leave it empty.', 'affilicious'))
->set_conditional_logic(array(
'relation' => 'and',
array(
'field' => Carbon_Product_Repository::REVIEW_RATING,
'value' => 'none',
'compare' => '!=',
)
)),
);
return apply_filters('aff_admin_meta_box_render_product_container_review_fields', $fields);
}
/**
* Get the relation fields
*
* @since 0.9
* @return array
*/
protected function get_relations_fields()
{
$fields = array(
Carbon_Field::make('relationship', Carbon_Product_Repository::RELATED_PRODUCTS, __('Related Products', 'affilicious'))
->allow_duplicates(false)
->set_post_type(Product::POST_TYPE),
Carbon_Field::make('relationship', Carbon_Product_Repository::RELATED_ACCESSORIES, __('Related Accessories', 'affilicious'))
->allow_duplicates(false)
->set_post_type(Product::POST_TYPE),
);
// Remove the current post from the final result
add_filter('carbon_relationship_options', function($options, $name) {
if($name == Carbon_Product_Repository::RELATED_PRODUCTS || $name = Carbon_Product_Repository::RELATED_ACCESSORIES) {
$current_post = get_post();
foreach ($options as $key => $option) {
if($option['id'] == $current_post->ID || $option['is_trashed'] != false || $option['subtype'] != Product::POST_TYPE) {
unset($options[$key]);
}
}
}
return $options;
}, 10, 2);
return apply_filters('aff_admin_meta_box_render_product_container_relations_fields', $fields);
}
}