: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* @param array $rules Array with permalink rules.
* @return array $rules Updated array with permalink rules.
function prtfl_custom_permalinks( $rules ) {
if ( empty( $prtfl_options ) ) {
$prtfl_options = get_option( 'prtfl_options' );
if ( empty( $prtfl_options ) ) {
register_prtfl_settings();
if ( ! empty( $prtfl_options['page_id_portfolio_template'] ) ) {
$parent = get_post( $prtfl_options['page_id_portfolio_template'] );
if ( ! empty( $parent ) ) {
if ( ! isset( $rules[ '(.+)/' . $parent->post_name . '/([^/]+)/?$' ] ) || ! isset( $rules[ $parent->post_name . '/([^/]+)/?$' ] ) ) {
$newrules[ '(.+)/' . $parent->post_name . '/([^/]+)/?$' ] = 'index.php?post_type=' . $prtfl_options['post_type_name'] . '&name=$matches[2]&posts_per_page=-1';
$newrules[ $parent->post_name . '/([^/]+)/?$' ] = 'index.php?post_type=' . $prtfl_options['post_type_name'] . '&name=$matches[1]&posts_per_page=-1';
$newrules[ $parent->post_name . '/page/([^/]+)/?$' ] = 'index.php?pagename=' . $parent->post_name . '&paged=$matches[1]';
$newrules[ $parent->post_name . '/page/([^/]+)?$' ] = 'index.php?pagename=' . $parent->post_name . '&paged=$matches[1]';
/* fix feed permalink (<link rel="alternate" type="application/rss+xml" ... >) on the attachment single page (if the attachment is Attached to the portfolio page) */
if ( ! empty( $prtfl_options['slug'] ) ) {
$newrules[ $prtfl_options['slug'] . '/.+?/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$' ] = 'index.php?attachment=$matches[1]&feed=$matches[2]';
$newrules[ $prtfl_options['slug'] . '/.+?/([^/]+)/(feed|rdf|rss|rss2|atom)/?$' ] = 'index.php?attachment=$matches[1]&feed=$matches[2]';
return array_merge( $newrules, $rules );
if ( ! function_exists( 'prtfl_template_include' ) ) {
* Load a template. Handles template usage so that plugin can use own templates instead of the themes.
* Templates are in the 'templates' folder.
* overrides in /{theme}/bws-templates/ by default.
* @param mixed $template Template for this post.
* @return string $template New template.
function prtfl_template_include( $template ) {
global $prtfl_options, $wp_query, $prtfl_plugin_info;
if ( ! $prtfl_plugin_info ) {
if ( ! function_exists( 'get_plugin_data' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
$prtfl_plugin_info = get_plugin_data( __FILE__ );
if ( function_exists( 'is_embed' ) && is_embed() ) {
$post_type = get_post_type();
if ( is_single() && $prtfl_options['post_type_name'] === $post_type ) {
$file = 'portfolio-post.php';
} elseif ( $prtfl_options['post_type_name'] === $post_type && ( isset( $wp_query->query_vars['technologies'] ) || isset( $wp_query->query_vars['portfolio_executor_profile'] ) ) ) {
} elseif ( ! empty( $prtfl_options['page_id_portfolio_template'] ) && is_page( $prtfl_options['page_id_portfolio_template'] ) ) {
if ( ! wp_script_is( 'prtfl_front_script', 'registered' ) ) {
wp_register_script( 'prtfl_front_script', plugins_url( 'js/front_script.js', __FILE__ ), array( 'jquery' ), $prtfl_plugin_info['Version'], true );
$find = array( $file, 'bws-templates/' . $file );
$template = locate_template( $find );
$template = untrailingslashit( plugin_dir_path( __FILE__ ) ) . '/templates/' . $file;
if ( ! function_exists( 'prtfl_init_metaboxes' ) ) {
* Initialization of all metaboxes on the 'Add Portfolio' and Edit Portfolio pages
function prtfl_init_metaboxes() {
add_meta_box( 'prtfl_metabox_images', __( 'Images', 'portfolio' ), 'prtfl_metabox_images_block', $prtfl_options['post_type_name'], 'normal', 'high' );
add_meta_box( 'Portfolio-Info', __( 'General', 'portfolio' ), 'prtfl_post_custom_box', $prtfl_options['post_type_name'], 'normal', 'high' );
$bws_hide_premium_options_check = bws_hide_premium_options_check( $prtfl_options );
if ( ! $bws_hide_premium_options_check ) {
add_meta_box( 'prtfl_categories_meta_box', __( 'Categories', 'portfolio' ), 'prtfl_categories_meta_box', $prtfl_options['post_type_name'], 'side', 'low' );
add_meta_box( 'prtfl_sectors_meta_box', __( 'Sectors', 'portfolio' ), 'prtfl_sectors_meta_box', $prtfl_options['post_type_name'], 'side', 'low' );
add_meta_box( 'prtfl_services_meta_box', __( 'Services', 'portfolio' ), 'prtfl_services_meta_box', $prtfl_options['post_type_name'], 'side', 'low' );
if ( ! function_exists( 'prtfl_post_custom_box' ) ) {
* Create custom meta box for portfolio post type
* @param string $obj Object.
* @param array $box Box array.
function prtfl_post_custom_box( $obj = '', $box = '' ) {
global $prtfl_boxes, $prtfl_plugin_info, $wp_version, $prtfl_options;
/* Generate box contents */
foreach ( $prtfl_boxes[ $box['id'] ] as $box ) {
echo wp_kses_post( prtfl_general_field( $box ) );
$bws_hide_premium_options_check = bws_hide_premium_options_check( $prtfl_options );
if ( ! $bws_hide_premium_options_check ) {
<div class="bws_pro_version_bloc">
<div class="bws_pro_version_table_bloc">
<div class="bws_table_bg" style="top: 0px; z-index: 2;"></div>
<div class="portfolio_admin_box">
<p><label for="prtfl_client"><strong><?php esc_html_e( 'Client', 'portfolio' ); ?></strong></label></p>
/* display visual editor */
'textarea_name' => 'prtfl_client',
wp_editor( '', 'prtfl_client', $settings );
<div class="portfolio_admin_box">
<p><label for="prtfl_featured"><strong><?php esc_html_e( 'Featured project', 'portfolio' ); ?></strong></label></p>
<p><input id="prtfl_featured" disabled="disabled" type="checkbox" name="prtfl_featured" value="1" />
<em><?php esc_html_e( 'Add to slider', 'portfolio' ); ?></em>
<div class="bws_pro_version_tooltip">
<a class="bws_button" href="https://bestwebsoft.com/products/wordpress/plugins/portfolio/?k=f047e20c92c972c398187a4f70240285&pn=74&v=<?php echo esc_attr( $prtfl_plugin_info['Version'] ); ?>&wp_v=<?php echo esc_attr( $wp_version ); ?>" target="_blank" title="Portfolio Pro Plugin" style="z-index: 3;" ><?php esc_html_e( 'Learn More', 'portfolio' ); ?></a>
<div class="clear"></div>
if ( ! function_exists( 'prtfl_general_field' ) ) {
* This is the field meta box
* @param array $args Array of data for meta box.
function prtfl_general_field( $args ) {
$post_meta = get_post_meta( $post->ID, 'prtfl_information', true );
$value = ! empty( $post_meta ) && is_array( $post_meta ) && ! empty( $post_meta[ $args['name'] ] ) ? $post_meta[ $args['name'] ] : '';
<div class="portfolio_admin_box">
<p><label for="<?php echo esc_attr( $args['name'] ); ?>"><strong><?php echo esc_html( $args['title'] ); ?></strong></label></p>
<p><input id="<?php echo esc_attr( $args['name'] ); ?>" type="text" style="width:80%;" name="<?php echo esc_attr( $args['name'] ); ?>" value="<?php echo esc_html( $value ); ?>" /></p>
if ( ! function_exists( 'prtfl_categories_meta_box' ) ) {
* Banner on Portfolio Edit Page
function prtfl_categories_meta_box() {
global $prtfl_plugin_info, $wp_version;
<div class="bws_pro_version_bloc">
<div class="bws_pro_version_table_bloc">
<div class="bws_table_bg" style="top: 0px;"></div>
<div class="prtfl_portfolio_categoriesdiv">
<ul class="category-tabs">
<li class="tabs"><a href="#"><?php esc_html_e( 'All Categories', 'portfolio' ); ?></a></li>
<li><a href="#"><?php esc_html_e( 'Most Used', 'portfolio' ); ?></a></li>
<div class="tabs-panel" style="display: none;">
<ul class="categorychecklist form-no-clear">
<li class="popular-category">
<label class="selectit"><input checked="checked" disabled="disabled" value="236" type="checkbox" /><?php esc_html_e( 'Uncatgorized', 'portfolio' ); ?></label>
<ul class="categorychecklist form-no-clear">
<li class="popular-category"><label class="selectit"><input value="236" name="tax_input[portfolio_categories][]" checked="checked" disabled="disabled" type="checkbox" /> <?php esc_html_e( 'Uncatgorized', 'portfolio' ); ?></label></li>
<div class="bws_pro_version_tooltip">
<a class="bws_button" href="https://bestwebsoft.com/products/wordpress/plugins/portfolio/?k=f047e20c92c972c398187a4f70240285&pn=74&v=<?php echo esc_attr( $prtfl_plugin_info['Version'] ); ?>&wp_v=<?php echo esc_attr( $wp_version ); ?>" target="_blank" title="Portfolio Pro Plugin"><?php esc_html_e( 'Learn More', 'portfolio' ); ?></a>
<div class="clear"></div>
if ( ! function_exists( 'prtfl_sectors_meta_box' ) ) {
* Banner on Portfolio Edit Page
function prtfl_sectors_meta_box() {
global $prtfl_plugin_info, $wp_version;
<div class="bws_pro_version_bloc">
<div class="bws_pro_version_table_bloc">
<div class="bws_table_bg" style="top: 0px;"></div>
<div class="prtfl_portfolio_sectorsdiv">
<ul class="category-tabs">
<li class="tabs"><a href="#"><?php esc_html_e( 'All Sectors', 'portfolio' ); ?></a></li>
<li><a href="#"><?php esc_html_e( 'Most Used', 'portfolio' ); ?></a></li>
<div class="tabs-panel" style="display: none;">
<ul class="categorychecklist form-no-clear">
<li class="popular-category">
<label class="selectit"><input disabled="disabled" value="236" type="checkbox" /><?php esc_html_e( 'Uncatgorized', 'portfolio' ); ?></label>
<ul class="categorychecklist form-no-clear">
<li class="popular-category"><label class="selectit"><input value="236" name="tax_input[portfolio_sectors][]" disabled="disabled" type="checkbox" /> <?php esc_html_e( 'Sector', 'portfolio' ); ?> 1</label></li>
<li class="popular-category"><label class="selectit"><input value="237" name="tax_input[portfolio_sectors][]" disabled="disabled" type="checkbox" /> <?php esc_html_e( 'Sector', 'portfolio' ); ?> 2</label></li>
<div class="bws_pro_version_tooltip">
<a class="bws_button" href="https://bestwebsoft.com/products/wordpress/plugins/portfolio/?k=f047e20c92c972c398187a4f70240285&pn=74&v=<?php echo esc_attr( $prtfl_plugin_info['Version'] ); ?>&wp_v=<?php echo esc_attr( $wp_version ); ?>" target="_blank" title="Portfolio Pro Plugin"><?php esc_html_e( 'Learn More', 'portfolio' ); ?></a>
<div class="clear"></div>
if ( ! function_exists( 'prtfl_services_meta_box' ) ) {
* Banner on Portfolio Edit Page
function prtfl_services_meta_box() {
global $prtfl_plugin_info, $wp_version;
<div class="bws_pro_version_bloc">
<div class="bws_pro_version_table_bloc">
<div class="bws_table_bg" style="top: 0px;"></div>
<div class="prtfl_portfolio_servicesdiv">
<ul class="category-tabs">
<li class="tabs"><a href="#"><?php esc_html_e( 'All Services', 'portfolio' ); ?></a></li>
<li><a href="#"><?php esc_html_e( 'Most Used', 'portfolio' ); ?></a></li>
<div class="tabs-panel" style="display: none;">
<ul class="categorychecklist form-no-clear">
<li class="popular-category">
<label class="selectit"><input disabled="disabled" value="236" type="checkbox" /><?php esc_html_e( 'Uncatgorized', 'portfolio' ); ?></label>
<ul class="categorychecklist form-no-clear">
<li class="popular-category"><label class="selectit"><input value="236" name="tax_input[portfolio_services][]" disabled="disabled" type="checkbox" /> <?php esc_html_e( 'Service', 'portfolio' ); ?> 1</label></li>
<li class="popular-category"><label class="selectit"><input value="237" name="tax_input[portfolio_services][]" disabled="disabled" type="checkbox" /> <?php esc_html_e( 'Service', 'portfolio' ); ?> 2</label></li>
<div class="bws_pro_version_tooltip">
<a class="bws_button" href="https://bestwebsoft.com/products/wordpress/plugins/portfolio/?k=f047e20c92c972c398187a4f70240285&pn=74&v=<?php echo esc_attr( $prtfl_plugin_info['Version'] ); ?>&wp_v=<?php echo esc_attr( $wp_version ); ?>" target="_blank" title="Portfolio Pro Plugin"><?php esc_html_e( 'Learn More', 'portfolio' ); ?></a>
<div class="clear"></div>
if ( ! function_exists( 'prtfl_metabox_images_block' ) ) {
function prtfl_metabox_images_block() {
<div id="prtfl_images_container">
<noscript><div class="error"><p><?php esc_html_e( 'Please enable JavaScript to add or delete images.', 'portfolio' ); ?></p></div></noscript>
if ( metadata_exists( 'post', $post->ID, '_prtfl_images' ) ) {
$prtfl_images = get_post_meta( $post->ID, '_prtfl_images', true );
/* Compatibility with old version 1.0.3 */
'post_parent' => $post->ID,
'post_type' => 'attachment',
'post_mime_type' => 'image',
'orderby' => 'menu_order',
'exclude' => get_post_thumbnail_id(),
$attachments = get_children( $args );
$prtfl_images = implode( ',', $attachments );
$attachments = array_filter( explode( ',', $prtfl_images ) );
if ( ! empty( $attachments ) ) {
foreach ( $attachments as $attachment_id ) {
$attachment = wp_get_attachment_image( $attachment_id, 'thumbnail' );
/* skip if attachment is empty */
if ( empty( $attachment ) ) {
echo '<li class="prtfl_single_image" data-attachment_id="' . esc_attr( $attachment_id ) . '">
' . wp_kses_post( $attachment ) . '
<span class="prtfl_delete_image"><a href="#" title="' . esc_html__( 'Delete image', 'portfolio' ) . '">' . esc_html__( 'Delete', 'portfolio' ) . '</a></span>
$updated_images_ids[] = $attachment_id;
/* update product meta to set new portfolio ids */
update_post_meta( $post->ID, '_prtfl_images', implode( ',', $updated_images_ids ) );
<input type="hidden" id="prtfl_images" name="prtfl_images" value="<?php echo esc_attr( $prtfl_images ); ?>" />
<p class="prtfl_add_portfolio_images hide-if-no-js">
<a href="#" data-choose="<?php esc_attr_e( 'Add Images to Portfolio', 'portfolio' ); ?>" data-update="<?php esc_attr_e( 'Add to portfolio', 'portfolio' ); ?>" data-delete="<?php esc_attr_e( 'Delete image', 'portfolio' ); ?>" data-text="<?php esc_attr_e( 'Delete', 'portfolio' ); ?>"><?php esc_html_e( 'Add images', 'portfolio' ); ?></a>
if ( ! function_exists( 'prtfl_save_postdata' ) ) {
* Saves our custom data when the post is saved
* @param int $post_id Post ID.
* @param object $post Post object.
function prtfl_save_postdata( $post_id, $post ) {
global $prtfl_boxes, $prtfl_options;
if ( $prtfl_options['post_type_name'] === $post->post_type && ! wp_is_post_revision( $post_id ) && ! empty( $_POST ) ) {
* Don't store custom data twice
* Verify this came from the our screen and with proper authorization, because save_post can be triggered at other times
if ( ! current_user_can( 'edit_page', $post->ID ) ) {
/* We'll put it into an array to make it easier to loop though. The data is already in $prtfl_boxes, but we need to flatten it out. */
foreach ( $prtfl_boxes as $prtfl_boxe ) {
foreach ( $prtfl_boxe as $prtfl_fields ) {
if ( isset( $_POST[ $prtfl_fields['name'] ] ) ) {
if ( 'url' === $prtfl_fields['type'] ) {
$my_data[ $prtfl_fields['name'] ] = esc_url( wp_unslash( $_POST[ $prtfl_fields['name'] ] ) );
$my_data[ $prtfl_fields['name'] ] = sanitize_text_field( wp_unslash( $_POST[ $prtfl_fields['name'] ] ) );
if ( isset( $my_data ) ) {
/* Add values of $my_data as custom fields. Let's cycle through the $my_data array! */
if ( get_post_meta( $post->ID, 'prtfl_information', false ) ) {
/* Custom field has a value and this custom field exists in database */
update_post_meta( $post->ID, 'prtfl_information', $my_data );
/* Custom field does not have a value, but this custom field exists in database */
update_post_meta( $post->ID, 'prtfl_information', $my_data );
if ( isset( $_POST['prtfl_images'] ) ) {
$attachment_ids = ! empty( $_POST['prtfl_images'] ) ? array_filter( explode( ',', sanitize_text_field( wp_unslash( $_POST['prtfl_images'] ) ) ) ) : array();
update_post_meta( $post_id, '_prtfl_images', implode( ',', $attachment_ids ) );
if ( ! function_exists( 'prtfl_content_save_pre' ) ) {
* Replace shortcode [latest_portfolio_items] from portfolio content before portfolio saving
* @param string $content Content.
* @returnm string $content Content.
function prtfl_content_save_pre( $content ) {
global $post, $prtfl_options;
if ( isset( $post ) && $prtfl_options['post_type_name'] === $post->post_type && ! wp_is_post_revision( $post->ID ) && ! empty( $_POST ) ) {
$content = preg_replace( '/\[latest_portfolio_items count=[\d]*\]/', '', $content );
if ( ! function_exists( 'prtfl_add_pdf_print_content' ) ) {
* Add custom fields and images for PDF&Print plugin in Portfolio post
* @param string $content Contetn for print.
function prtfl_add_pdf_print_content( $content ) {
global $post, $prtfl_options;
$current_post_type = get_post_type();
if ( ! $prtfl_options ) {
$prtfl_options = get_option( 'prtfl_options' );
if ( $prtfl_options['post_type_name'] === $current_post_type && ! empty( $post ) ) {
if ( ! $prtfl_options ) {
$prtfl_options = get_option( 'prtfl_options' );
$post_meta = get_post_meta( $post->ID, 'prtfl_information', true );
$user_id = get_current_user_id();
if ( 1 === absint( $prtfl_options['date_additional_field'] ) ) {
$date_compl = isset( $post_meta['_prtfl_date_compl'] ) ? $post_meta['_prtfl_date_compl'] : '';
if ( ! empty( $date_compl ) ) {
$custom_content .= '<p><span class="lable">' . $prtfl_options['date_text_field'] . ' </span> ' . $date_compl . '</p>';
if ( 1 === absint( $prtfl_options['link_additional_field'] ) && ! empty( $post_meta['_prtfl_link'] ) ) {
if ( false !== wp_parse_url( $post_meta['_prtfl_link'] ) ) {
if ( ( 0 === $user_id && 0 === absint( $prtfl_options['link_additional_field_for_non_registered'] ) ) || 0 !== $user_id ) {
$custom_content .= '<p><span class="lable">' . $prtfl_options['link_text_field'] . '</span> <a href="' . $post_meta['_prtfl_link'] . '">' . $post_meta['_prtfl_link'] . '</a></p>';
$custom_content .= '<p><span class="lable">' . $prtfl_options['link_text_field'] . '</span> ' . $post_meta['_prtfl_link'] . '</p>';
$custom_content .= '<p><span class="lable">' . $prtfl_options['link_text_field'] . '</span> ' . $post_meta['_prtfl_link'] . '</p>';
if ( 0 !== $user_id || 0 === absint( $prtfl_options['svn_additional_field_for_non_logged'] ) ) {
if ( 1 === absint( $prtfl_options['svn_additional_field'] ) && ! empty( $post_meta['_prtfl_svn'] ) ) {
$custom_content .= '<p><span class="lable">' . $prtfl_options['svn_text_field'] . '</span> ' . $post_meta['_prtfl_svn'] . '</p>';
if ( 1 === absint( $prtfl_options['executor_additional_field'] ) ) {
$executors_profile = wp_get_object_terms( $post->ID, 'portfolio_executor_profile' );
if ( ! empty( $executors_profile ) ) {
$custom_content .= '<p><span class="lable">' . $prtfl_options['executor_text_field'] . '</span>';
foreach ( $executors_profile as $profile ) {
$custom_content .= '<a href="' . get_term_link( $profile->slug, 'portfolio_executor_profile' ) . '" title="' . $profile->name . ' profile" target="_blank">' . $profile->name . '</a>';
$custom_content .= '</p>';