Set Silex 2 application locale in a service controller from route - silex

How can I get the locale from the route and use it in the service controller?
Here is my service controller:
$app['clients.controller'] = function() use ($app) {
$clientTranslator = new ClientTranslator;
$translations = $clientTranslator->getTranslations();
foreach ($translations as $domain => $data) {
foreach ($data as $locale => $messages) {
$app['translator']->addResource('array', $messages, $locale, $domain);
}
}
$app['translator']->setLocale($app['locale']);
return new ClientController($app, $app['clients.model'], $app['clients.validator']);
};
Notice that I am trying to set the translator locale from the app locale.
And here are the routes calling this service controller:
$app->mount ( '/en', function ($client) use ($app) {
$app ['locale'] = "en";
$client->match ( '/{id}/edit', 'clients.controller:editAction')
->assert ( 'id', '\d+' )
->method ( 'GET|POST' );
$client->match ( '/add', 'clients.controller:addAction')
->method ( 'GET|POST' );
$client->match ( '/{id}', 'clients.controller:deleteAction' )
->assert ( 'id', '\d+' )
->method ( 'DELETE' );
$client->get('/', "clients.controller:indexAction");
});
$app->mount('/fr', function ($client) use ($app) {
$app['locale'] = "fr";
$client->match ( '/{id}/edit', 'clients.controller:editAction')
->assert ( 'id', '\d+' )
->method ( 'GET|POST' );
$client->match ( '/add', 'clients.controller:addAction' )
->method ( 'GET|POST' );
$client->match ( '/{id}', 'clients.controller:deleteAction' )
->assert ( 'id', '\d+' )
->method ( 'DELETE' );
$client->get ( '/', "clients.controller:indexAction" );
} );
What is happening now is that the app locale is always French. I understand now that the statements in the mount section are executed even if that route is not called.
What would be the right way to achieve what I want?
Thanks

The right way for the routes in this case is as follows
$app->mount ( '{_locale}/', function ($client) use ($app) {
$client->match ( '/{id}/edit', 'clients.controller:editAction')
->assert ( 'id', '\d+' )
->method ( 'GET|POST' );
$client->match ( '/add', 'clients.controller:addAction')
->method ( 'GET|POST' );
$client->match ( '/{id}', 'clients.controller:deleteAction' )
->assert ( 'id', '\d+' )
->method ( 'DELETE' );
$client->get('/', "clients.controller:indexAction");
});
This way the locale is automatically set.

Related

How to alter woocommerce widget filter by attribute widget?

I use the default Woocommerce widget "Filter by attribute" and I would like to prepend the name of each attributes.
But I don't find any hook on it
Do you know how to achieve this ?
What about extending its class to override the widget?
in your functions.php, add this class, you can then change the elements or do conditional statements depending on what you need.
/**
* Layered nav widget
*
* #package WooCommerce/Widgets
* #version 2.6.0
*/
/**
* Widget layered nav class.
*/
class The_New_Attribute_Widget extends WC_Widget_Layered_Nav {
/**
* Constructor.
*/
public function __construct() {
$this->widget_cssclass = 'woocommerce widget_layered_nav woocommerce-widget-layered-nav';
$this->widget_description = __( 'Display a list of attributes to filter products in your store.', 'woocommerce' );
$this->widget_id = 'woocommerce_layered_nav';
$this->widget_name = __( 'Filter Products by Attribute', 'woocommerce' );
parent::__construct();
}
/**
* Updates a particular instance of a widget.
*
* #see WP_Widget->update
*
* #param array $new_instance New Instance.
* #param array $old_instance Old Instance.
*
* #return array
*/
public function update( $new_instance, $old_instance ) {
$this->init_settings();
return parent::update( $new_instance, $old_instance );
}
/**
* Outputs the settings update form.
*
* #see WP_Widget->form
*
* #param array $instance Instance.
*/
public function form( $instance ) {
$this->init_settings();
parent::form( $instance );
}
/**
* Init settings after post types are registered.
*/
public function init_settings() {
$attribute_array = array();
$std_attribute = '';
$attribute_taxonomies = wc_get_attribute_taxonomies();
if ( ! empty( $attribute_taxonomies ) ) {
foreach ( $attribute_taxonomies as $tax ) {
if ( taxonomy_exists( wc_attribute_taxonomy_name( $tax->attribute_name ) ) ) {
$attribute_array[ $tax->attribute_name ] = $tax->attribute_name;
}
}
$std_attribute = current( $attribute_array );
}
$this->settings = array(
'title' => array(
'type' => 'text',
'std' => __( 'Filter by', 'woocommerce' ),
'label' => __( 'Title', 'woocommerce' ),
),
'attribute' => array(
'type' => 'select',
'std' => $std_attribute,
'label' => __( 'Attribute', 'woocommerce' ),
'options' => $attribute_array,
),
'display_type' => array(
'type' => 'select',
'std' => 'list',
'label' => __( 'Display type', 'woocommerce' ),
'options' => array(
'list' => __( 'List', 'woocommerce' ),
'dropdown' => __( 'Dropdown', 'woocommerce' ),
),
),
'query_type' => array(
'type' => 'select',
'std' => 'and',
'label' => __( 'Query type', 'woocommerce' ),
'options' => array(
'and' => __( 'AND', 'woocommerce' ),
'or' => __( 'OR', 'woocommerce' ),
),
),
);
}
/**
* Get this widgets taxonomy.
*
* #param array $instance Array of instance options.
* #return string
*/
protected function get_instance_taxonomy( $instance ) {
if ( isset( $instance['attribute'] ) ) {
return wc_attribute_taxonomy_name( $instance['attribute'] );
}
$attribute_taxonomies = wc_get_attribute_taxonomies();
if ( ! empty( $attribute_taxonomies ) ) {
foreach ( $attribute_taxonomies as $tax ) {
if ( taxonomy_exists( wc_attribute_taxonomy_name( $tax->attribute_name ) ) ) {
return wc_attribute_taxonomy_name( $tax->attribute_name );
}
}
}
return '';
}
/**
* Get this widgets query type.
*
* #param array $instance Array of instance options.
* #return string
*/
protected function get_instance_query_type( $instance ) {
return isset( $instance['query_type'] ) ? $instance['query_type'] : 'and';
}
/**
* Get this widgets display type.
*
* #param array $instance Array of instance options.
* #return string
*/
protected function get_instance_display_type( $instance ) {
return isset( $instance['display_type'] ) ? $instance['display_type'] : 'list';
}
/**
* Output widget.
*
* #see WP_Widget
*
* #param array $args Arguments.
* #param array $instance Instance.
*/
public function widget( $args, $instance ) {
if ( ! is_shop() && ! is_product_taxonomy() ) {
return;
}
$_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes();
$taxonomy = $this->get_instance_taxonomy( $instance );
$query_type = $this->get_instance_query_type( $instance );
$display_type = $this->get_instance_display_type( $instance );
if ( ! taxonomy_exists( $taxonomy ) ) {
return;
}
$terms = get_terms( $taxonomy, array( 'hide_empty' => '1' ) );
if ( 0 === count( $terms ) ) {
return;
}
ob_start();
$this->widget_start( $args, $instance );
if ( 'dropdown' === $display_type ) {
wp_enqueue_script( 'selectWoo' );
wp_enqueue_style( 'select2' );
$found = $this->layered_nav_dropdown( $terms, $taxonomy, $query_type );
} else {
$found = $this->layered_nav_list( $terms, $taxonomy, $query_type );
}
$this->widget_end( $args );
// Force found when option is selected - do not force found on taxonomy attributes.
if ( ! is_tax() && is_array( $_chosen_attributes ) && array_key_exists( $taxonomy, $_chosen_attributes ) ) {
$found = true;
}
if ( ! $found ) {
ob_end_clean();
} else {
echo ob_get_clean(); // #codingStandardsIgnoreLine
}
}
/**
* Return the currently viewed taxonomy name.
*
* #return string
*/
protected function get_current_taxonomy() {
return is_tax() ? get_queried_object()->taxonomy : '';
}
/**
* Return the currently viewed term ID.
*
* #return int
*/
protected function get_current_term_id() {
return absint( is_tax() ? get_queried_object()->term_id : 0 );
}
/**
* Return the currently viewed term slug.
*
* #return int
*/
protected function get_current_term_slug() {
return absint( is_tax() ? get_queried_object()->slug : 0 );
}
/**
* Show dropdown layered nav.
*
* #param array $terms Terms.
* #param string $taxonomy Taxonomy.
* #param string $query_type Query Type.
* #return bool Will nav display?
*/
protected function layered_nav_dropdown( $terms, $taxonomy, $query_type ) {
global $wp;
$found = false;
if ( $taxonomy !== $this->get_current_taxonomy() ) {
$term_counts = $this->get_filtered_term_product_counts( wp_list_pluck( $terms, 'term_id' ), $taxonomy, $query_type );
$_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes();
$taxonomy_filter_name = wc_attribute_taxonomy_slug( $taxonomy );
$taxonomy_label = wc_attribute_label( $taxonomy );
/* translators: %s: taxonomy name */
$any_label = apply_filters( 'woocommerce_layered_nav_any_label', sprintf( __( 'Any %s', 'woocommerce' ), $taxonomy_label ), $taxonomy_label, $taxonomy );
$multiple = 'or' === $query_type;
$current_values = isset( $_chosen_attributes[ $taxonomy ]['terms'] ) ? $_chosen_attributes[ $taxonomy ]['terms'] : array();
if ( '' === get_option( 'permalink_structure' ) ) {
$form_action = remove_query_arg( array( 'page', 'paged' ), add_query_arg( $wp->query_string, '', home_url( $wp->request ) ) );
} else {
$form_action = preg_replace( '%\/page/[0-9]+%', '', home_url( trailingslashit( $wp->request ) ) );
}
echo '<form method="get" action="' . esc_url( $form_action ) . '" class="woocommerce-widget-layered-nav-dropdown">';
echo '<select class="woocommerce-widget-layered-nav-dropdown dropdown_layered_nav_' . esc_attr( $taxonomy_filter_name ) . '"' . ( $multiple ? 'multiple="multiple"' : '' ) . '>';
echo '<option value="">' . esc_html( $any_label ) . '</option>';
foreach ( $terms as $term ) {
// If on a term page, skip that term in widget list.
if ( $term->term_id === $this->get_current_term_id() ) {
continue;
}
// Get count based on current view.
$option_is_set = in_array( $term->slug, $current_values, true );
$count = isset( $term_counts[ $term->term_id ] ) ? $term_counts[ $term->term_id ] : 0;
// Only show options with count > 0.
if ( 0 < $count ) {
$found = true;
} elseif ( 0 === $count && ! $option_is_set ) {
continue;
}
echo '<option value="' . esc_attr( urldecode( $term->slug ) ) . '" ' . selected( $option_is_set, true, false ) . '>' . esc_html( $term->name ) . '</option>';
}
echo '</select>';
if ( $multiple ) {
echo '<button class="woocommerce-widget-layered-nav-dropdown__submit" type="submit" value="' . esc_attr__( 'Apply', 'woocommerce' ) . '">' . esc_html__( 'Apply', 'woocommerce' ) . '</button>';
}
if ( 'or' === $query_type ) {
echo '<input type="hidden" name="query_type_' . esc_attr( $taxonomy_filter_name ) . '" value="or" />';
}
echo '<input type="hidden" name="filter_' . esc_attr( $taxonomy_filter_name ) . '" value="' . esc_attr( implode( ',', $current_values ) ) . '" />';
echo wc_query_string_form_fields( null, array( 'filter_' . $taxonomy_filter_name, 'query_type_' . $taxonomy_filter_name ), '', true ); // #codingStandardsIgnoreLine
echo '</form>';
wc_enqueue_js(
"
// Update value on change.
jQuery( '.dropdown_layered_nav_" . esc_js( $taxonomy_filter_name ) . "' ).change( function() {
var slug = jQuery( this ).val();
jQuery( ':input[name=\"filter_" . esc_js( $taxonomy_filter_name ) . "\"]' ).val( slug );
// Submit form on change if standard dropdown.
if ( ! jQuery( this ).attr( 'multiple' ) ) {
jQuery( this ).closest( 'form' ).submit();
}
});
// Use Select2 enhancement if possible
if ( jQuery().selectWoo ) {
var wc_layered_nav_select = function() {
jQuery( '.dropdown_layered_nav_" . esc_js( $taxonomy_filter_name ) . "' ).selectWoo( {
placeholder: decodeURIComponent('" . rawurlencode( (string) wp_specialchars_decode( $any_label ) ) . "'),
minimumResultsForSearch: 5,
width: '100%',
allowClear: " . ( $multiple ? 'false' : 'true' ) . ",
language: {
noResults: function() {
return '" . esc_js( _x( 'No matches found', 'enhanced select', 'woocommerce' ) ) . "';
}
}
} );
};
wc_layered_nav_select();
}
"
);
}
return $found;
}
/**
* Count products within certain terms, taking the main WP query into consideration.
*
* This query allows counts to be generated based on the viewed products, not all products.
*
* #param array $term_ids Term IDs.
* #param string $taxonomy Taxonomy.
* #param string $query_type Query Type.
* #return array
*/
protected function get_filtered_term_product_counts( $term_ids, $taxonomy, $query_type ) {
global $wpdb;
$tax_query = WC_Query::get_main_tax_query();
$meta_query = WC_Query::get_main_meta_query();
if ( 'or' === $query_type ) {
foreach ( $tax_query as $key => $query ) {
if ( is_array( $query ) && $taxonomy === $query['taxonomy'] ) {
unset( $tax_query[ $key ] );
}
}
}
$meta_query = new WP_Meta_Query( $meta_query );
$tax_query = new WP_Tax_Query( $tax_query );
$meta_query_sql = $meta_query->get_sql( 'post', $wpdb->posts, 'ID' );
$tax_query_sql = $tax_query->get_sql( $wpdb->posts, 'ID' );
// Generate query.
$query = array();
$query['select'] = "SELECT COUNT( DISTINCT {$wpdb->posts}.ID ) as term_count, terms.term_id as term_count_id";
$query['from'] = "FROM {$wpdb->posts}";
$query['join'] = "
INNER JOIN {$wpdb->term_relationships} AS term_relationships ON {$wpdb->posts}.ID = term_relationships.object_id
INNER JOIN {$wpdb->term_taxonomy} AS term_taxonomy USING( term_taxonomy_id )
INNER JOIN {$wpdb->terms} AS terms USING( term_id )
" . $tax_query_sql['join'] . $meta_query_sql['join'];
$query['where'] = "
WHERE {$wpdb->posts}.post_type IN ( 'product' )
AND {$wpdb->posts}.post_status = 'publish'"
. $tax_query_sql['where'] . $meta_query_sql['where'] .
'AND terms.term_id IN (' . implode( ',', array_map( 'absint', $term_ids ) ) . ')';
$search = WC_Query::get_main_search_query_sql();
if ( $search ) {
$query['where'] .= ' AND ' . $search;
}
$query['group_by'] = 'GROUP BY terms.term_id';
$query = apply_filters( 'woocommerce_get_filtered_term_product_counts_query', $query );
$query = implode( ' ', $query );
// We have a query - let's see if cached results of this query already exist.
$query_hash = md5( $query );
// Maybe store a transient of the count values.
$cache = apply_filters( 'woocommerce_layered_nav_count_maybe_cache', true );
if ( true === $cache ) {
$cached_counts = (array) get_transient( 'wc_layered_nav_counts_' . sanitize_title( $taxonomy ) );
} else {
$cached_counts = array();
}
if ( ! isset( $cached_counts[ $query_hash ] ) ) {
$results = $wpdb->get_results( $query, ARRAY_A ); // #codingStandardsIgnoreLine
$counts = array_map( 'absint', wp_list_pluck( $results, 'term_count', 'term_count_id' ) );
$cached_counts[ $query_hash ] = $counts;
if ( true === $cache ) {
set_transient( 'wc_layered_nav_counts_' . sanitize_title( $taxonomy ), $cached_counts, DAY_IN_SECONDS );
}
}
return array_map( 'absint', (array) $cached_counts[ $query_hash ] );
}
/**
* Show list based layered nav.
*
* #param array $terms Terms.
* #param string $taxonomy Taxonomy.
* #param string $query_type Query Type.
* #return bool Will nav display?
*/
protected function layered_nav_list( $terms, $taxonomy, $query_type ) {
// List display.
echo '<ul class="woocommerce-widget-layered-nav-list">';
$term_counts = $this->get_filtered_term_product_counts( wp_list_pluck( $terms, 'term_id' ), $taxonomy, $query_type );
$_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes();
$found = false;
$base_link = $this->get_current_page_url();
foreach ( $terms as $term ) {
$current_values = isset( $_chosen_attributes[ $taxonomy ]['terms'] ) ? $_chosen_attributes[ $taxonomy ]['terms'] : array();
$option_is_set = in_array( $term->slug, $current_values, true );
$count = isset( $term_counts[ $term->term_id ] ) ? $term_counts[ $term->term_id ] : 0;
// Skip the term for the current archive.
if ( $this->get_current_term_id() === $term->term_id ) {
continue;
}
// Only show options with count > 0.
if ( 0 < $count ) {
$found = true;
} elseif ( 0 === $count && ! $option_is_set ) {
continue;
}
$filter_name = 'filter_' . wc_attribute_taxonomy_slug( $taxonomy );
$current_filter = isset( $_GET[ $filter_name ] ) ? explode( ',', wc_clean( wp_unslash( $_GET[ $filter_name ] ) ) ) : array(); // WPCS: input var ok, CSRF ok.
$current_filter = array_map( 'sanitize_title', $current_filter );
if ( ! in_array( $term->slug, $current_filter, true ) ) {
$current_filter[] = $term->slug;
}
$link = remove_query_arg( $filter_name, $base_link );
// Add current filters to URL.
foreach ( $current_filter as $key => $value ) {
// Exclude query arg for current term archive term.
if ( $value === $this->get_current_term_slug() ) {
unset( $current_filter[ $key ] );
}
// Exclude self so filter can be unset on click.
if ( $option_is_set && $value === $term->slug ) {
unset( $current_filter[ $key ] );
}
}
if ( ! empty( $current_filter ) ) {
asort( $current_filter );
$link = add_query_arg( $filter_name, implode( ',', $current_filter ), $link );
// Add Query type Arg to URL.
if ( 'or' === $query_type && ! ( 1 === count( $current_filter ) && $option_is_set ) ) {
$link = add_query_arg( 'query_type_' . wc_attribute_taxonomy_slug( $taxonomy ), 'or', $link );
}
$link = str_replace( '%2C', ',', $link );
}
if ( $count > 0 || $option_is_set ) {
$link = apply_filters( 'woocommerce_layered_nav_link', $link, $term, $taxonomy );
$term_html = '<a rel="nofollow" href="' . esc_url( $link ) . '">' . esc_html( $term->name ) . '</a>';
} else {
$link = false;
$term_html = '<span>' . esc_html( $term->name ) . '</span>';
}
$term_html .= ' ' . apply_filters( 'woocommerce_layered_nav_count', '<span class="count">(' . absint( $count ) . ')</span>', $count, $term );
echo '<li class="woocommerce-widget-layered-nav-list__item wc-layered-nav-term ' . ( $option_is_set ? 'woocommerce-widget-layered-nav-list__item--chosen chosen' : '' ) . '">';
echo apply_filters( 'woocommerce_layered_nav_term_html', $term_html, $term, $link, $count ); // WPCS: XSS ok.
echo '</li>';
}
echo '</ul>';
return $found;
}
}
then in your functions.php again, unregister the default attribute widget and register the new one above:
function your_widget_handler() {
unregister_widget( 'WC_Widget_Layered_Nav' ); //unregister
register_widget( 'The_New_Attribute_Widget' ); //Register the new class
}
add_action( 'widgets_init', 'your_widget_handler' );
I took a look at the source code and it seems that it's only possible if you chose "List" as the "Display type". If so, then there is a filter applied to the displayed elements:
apply_filters( 'woocommerce_layered_nav_term_html', $term_html, $term, $link, $count );
so in order to add custom filter, you can do:
function so_62519320_prepend_name( $term_html, $term, $link, $count ) {
// do stuff
return $some_modified_value;
}
add_filter( 'woocommerce_layered_nav_term_html', 'so_62519320_prepend_name', 10, 4 );
Unfortunately, if you chose "Dropdown" as the "Display type", then there are no filters applied and it seems that you can't modify labels. There's only
esc_html( $term->name )
used to display option labels, so the only way to change this is to change the value in the database.

Hook::exec is not working for a particular module

I am facing an issue regarding the hook::exec in my prestashop application, where module and hook method is installed properly. But when I tried to execute this module, it return false. Kindly suggest me. Module and hook method is showing in "Modules and Services / Positions" as well as ps_hook table in database.
Module base file is defined as :
public function __construct()
{
$this->name = 'callback';
$this->tab = 'front_office_features';
$this->version = '1.0';
$this->author = 'Amit Jha';
$this->need_instance = 0;
$this->ps_versions_compliancy = array('min' => '1.6', 'max' => _PS_VERSION_);
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l( 'Call Back' );
$this->description = $this->l( '....' );
$this->confirmUninstall = $this->l( 'Are you sure you want to uninstall? .... ' );
}
And Install method is as below:
if ( parent::install() && $this->registerHook( 'displayCallBack' ) && $this->registerHook( 'displayHeader' ) && $this->registerHook( 'displayCallBackCart' ) && $this->registerHook( 'displayCallBackLinkOnCartPopup' ) && $this->registerHook( 'displayCallBackLinkOnCartPopupWishlist' ) ) {
if ( !$this->alterTable( 'add' ) ) {
return false;
}
return true;
}
Hook Method:
public function hookDisplayCallBack( $params )
{
$results = CallBackServiceCore::searchDetail();
if ( count( $results ) <= 0 ) {
return;
}
foreach ( $results as $item ) {
$this->context->smarty->assign( array(
'description_text' => $item["description_text"],
'recall_promise' => $item["recall_promise"]
) );
}
$arrDate = $this->getCallingTime();
$this->context->smarty->assign( array(
'arrTimeList' => $arrDate,
'product_id' => $params["product"]->id,
'product_name' => $params["product"]->name,
'category' => $params["product"]->category
)
);
return $this->display( __file__, 'display.tpl' );
}
Please suggest where I made mistake.

Yii2 - input search with auto-complete

I am using default Yii2 library for auto-complete. How can I make it, so it is reading values from DB while user is typing?
This is code I have so far, but query is done when the page is created:
echo AutoComplete::widget([
'name' => 'tradeName',
'model' => TradeNames::find()->select('name')->all(),
'options' => [
'class' => 'form-control'
],
'clientOptions' => [
'source' => array_column(TradeNames::find()->select('name')->asArray()->all(), 'name'),
},
],
]);
I followed this advice
jqueryui.com/autocomplete/#multiple and have written next code
<div id="autocomplete" class="ui-widget">
<?= \yii\jui\AutoComplete::widget([
'attribute' => 'attribute',
'name' => 'tradeName',
'clientOptions' => [
'source' => \Yii::$container->get('JsExpression',['function(request, response) {
response( $.ui.autocomplete.filter( window.dataAsArray, extractLast( request.term ) ) );
}']),
'select' => \Yii::$container->get('JsExpression',['function(event, ui) {
var terms = split( this.value );
terms.pop();
terms.push( ui.item.value );
terms.push( "" );
this.value = terms.join( ", " );
return false;
}']),
'focus' => \Yii::$container->get('JsExpression',['function() {
return false;
}']),
]
]) ?>
</div>
<script>
window.dataAsArray = ['item1', 'item2', 'item3'];
function split( val ) {
return val.split( /,\s*/ );
}
function extractLast( term ) {
return split( term ).pop();
}
$(document).ready( function() {
$('#autocomplete').on('keydown', function( event ) {
if ( event.keyCode === $.ui.keyCode.TAB && $( this ).autocomplete( "instance" ).menu.active ) {
event.preventDefault();
}
});
});
</script>
maybe it help to someone
try this
use yii\jui\AutoComplete;
use yii\web\JsExpression;
<?php
$data = TradeNames::find()
->select(['name as value', 'name as label','id as id'])
->asArray()
->all();
echo 'Trade Names' .'<br>';
echo AutoComplete::widget([
'name' => 'tradeName',
'id' => 'trade_name',
'clientOptions' => [
'source' => $data,
// 'minLength'=>'3',
'autoFill'=>true,
'select' => new JsExpression("function( event, ui ) {
$('#memberssearch-family_name_id').val(ui.item.id);//#memberssearch-family_name_id is the id of hiddenInput.
}")],
]);
?>
<?= Html::activeHiddenInput($model, 'tradeName')?>

ZF 2 submiting forms using Ajax

i searched for a long time for some exemples of ajax forms in ZF2,but there is no explicit tutorials, if someone can help me, i'll be thinkful. i'm trying to call a controll's action using ajax
What is the problem in that? just use some js library to sent a ajax request and parse the response accordingly. you can call any controller action if you have set the routing correct. just like you access the normal url. You can either send back the JSON response or the HTML response depending on your requirements.
the zend framework render(output) the HTML as per the layout template, you can assume each action content are snippets than get included in the layout.
So that said to get AJAX response, just disable the layout for AJAX calls, that seems so simple ya, ok
so now where do we add layout disable code, you can do this before any action is invoked to do that include this code in application Module.php, we are attaching an event to check if the call is from AJAX
public function onBootstrap(EventInterface $e){
$eventManager = $e->getApplication()->getEventManager();
$eventManager->attach('dispatch', array($this, 'disableLayout'), 100);
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
}
Add a function under the same Module.php
public function disableLayout(EventInterface $event){
$result = $event->getResult();
if ($result instanceof \Zend\View\Model\ViewModel) {
$result->setTerminal($event->getRequest()->isXmlHttpRequest());
//setTerminal(true) disable the layout
}
}
This is one way of doing it, there are many more ways, if you don't want to disable layout for all request you can simply set the setTerminal(true) fetching the current viewmodel on any action, that need to be called by ajax request, this is just an example that would help to move in the right direction
my action code
public function indexAction() {
//$this->layout ( 'layout/pages' );
$this -> id = ( int )$this -> getEvent() -> getRouteMatch() -> getParam('id');
$this -> id_branche = ( int )$this -> getEvent() -> getRouteMatch() -> getParam('id_branche');
$this -> form = new CommentForm();
$this -> form -> get('submit') -> setAttribute('label', 'Add');
$request = $this -> getRequest();
//verifie le type de la requete
if ($request -> isPost()) {
$user = new user();
$comment = new comment();
$blog = new blog();
print 'j';
//Initialisation du formulaire e partir des donnees reues
$this -> form -> setData($request -> getPost());
//$this->form->setData($request->getQuery());
//Ajout des filtres de validation base sur l'objet user,comment
print '2';
//$form->setInputFilter($user->getInputFilter());
//Contrele les champs
if ($this -> form -> isValid()) {
print '3';
$user -> exchangeArray($this -> form -> getData());
$comment -> exchangeArray($this -> form -> getData());
print '4';
$validname = $this->checkuser($this->form->getValue('email'));
if($validname){
$this -> getUserTable() -> saveUser($user);}
else{print 'exist';}
print '5';
$lastUserId = $this -> getUserTable() -> getAdapter() -> getDriver() -> getLastGeneratedValue('id');
$this -> getCommentTable() -> addComment($comment, $lastUserId, $this -> id);
return $this->redirect ()->toRoute ( '#Blog', array ('controller' => 'index',) );
} else {
print 'not set';
}
} else {
$viewm = new ViewModel( array('blog' => $this -> getBlogTable() -> getBlog($this -> id, $this -> id_branche), 'comment' => $this -> getCommentTable() -> fetchJoin($this -> id), 'id' => $this -> id, 'id_branche' => $this -> id_branche, 'formComment' => $this -> form, ));
$viewm -> setTerminal(true);
return $viewm;
}
}
**my view**
$form = $formComment;
)
$form->setAttribute( 'action', '#');
?>
<h4>Leave comment</h4>
<?=$this->form()->openTag( $form )?>
<dl class="zend_form">
<?=$this->formInput ( $form->get( 'id' ) )?>
<div>
<?=$this->formLabel ( $form->get ( 'name' ) )?>
<?=$this->formInput ( $form->get ( 'name' ) )?>
<?=$this->formElementErrors ( $form->get ( 'name' ) )?>
<div id="nameInfo">Please enter your name?</div>
</div>
<div><?=$this->formLabel ( $form->get ( 'email' ) )?>
<?=$this->formInput ( $form->get ( 'email' ) )?>
<?=$this->formElementErrors ( $form->get ( 'email' ) )?>
<div id="emailInfo">Valid E-mail please, you will need it to log
in!</div>
</div>
<div><?=$this->formLabel ( $form->get ( 'site' ) )?>
<?=$this->formInput ( $form->get ( 'site' ) )?>
<?=$this->formElementErrors ( $form->get ( 'site' ) )?>
</div>
<div><?=$this->formLabel ( $form->get ( 'comment' ) )?>
<?=$this->formTextarea ( $form->get ( 'comment' ) )?>
<?=$this->formElementErrors ( $form->get ( 'comment' ) )?>
</div>
<div>
<?=$this->formInput ( $form->get ( 'submit' ) )?>
<?=$this->formElementErrors ( $form->get ( 'submit' ) )?>
</div>
</dl>
<?=$this->form ()->closeTag ( $form )?>

get_permalink to attachment not working

I have following code:
<?php
$args = array(
'post_type' => 'attachment',
'numberposts' => 12,
'post_status' => null
);
$attachments = get_posts( $args );
if ( $attachments ) {
foreach ( $attachments as $attachment ) {
echo '<li><a href="'.get_permalink( $attachment->ID ).'">';
echo wp_get_attachment_image( $attachment->ID, array('100', '100') );
echo '</a></li>';
}
}
?>
The point of this script is to show last added 12 photos (thumbs of it). And this works perfect. But I want to add second funcionality - link to the page where it comes from (usually native gallery embed into post/page)
The problem is that in this case the link is corrupted. It always links to the very first post. What I am doing wrong?
Try get_attachment_link($attachment->ID).
Or the_attachment_link($attachment->ID) to directly print the anchor tag with the URL
Here is the final version:)
<?php
$args = array(
'post_type' => 'attachment',
'numberposts' => 12,
'post_status' => null
);
$attachments = get_posts( $args );
if ( $attachments ) {
foreach ( $attachments as $attachment ) {
$url = get_permalink( $attachment->ID );
echo '<li><a href="'.strstr($url, '/attachment', true).'">';
echo wp_get_attachment_image( $attachment->ID, array('100', '100') );
echo '</a></li>';
}
}
?>
/attachment is the starting point from which we want to remove everything from the url.

Resources