WooCommerce Ajax Cart Update click only fires on first click

I want to do an AJAX update (a hidden update cart button click) of my WooCommerce cart when user changes the quantity.
I followed the steps here.

So basically it’s this code:

jQuery(document).ready(function($) {
    let timeout;
    $('.woocommerce').on( 'change', 'input.qty', function(){
        if ( timeout !== undefined ) {
            clearTimeout( timeout );
        }
        timeout = setTimeout(function() {
            $("[name='update_cart']").trigger("click"); // trigger cart update
        }, 1000 ); // 1 second delay, half a second (500) seems comfortable too
    });
});

I’ve added the above script like so:

function custom_enqueue_cart_scripts() {
    error_log('custom_enqueue_cart_scripts');
    if (is_cart()) {
        error_log('is_cart()');
        wp_enqueue_script('custom-cart', get_stylesheet_directory_uri() . '/js/custom-cart.js', array('jquery'), null, true);           

    }
}
add_action('wp_enqueue_scripts', 'custom_enqueue_cart_scripts');

However, it only works when I change the quantity for the first time. Any subsequent click is not registered. Why?

what should i do for file export of hidden data

i am using xampp for a page where for the database i am taking 3 columns of the data to be shown in a data-table. i want to make file export buttons (csv,excel,pdf,print) for all the data that is present in the table that i am using (without displaying them), for example i have total 10 columns in the table

what should be the ideal way to do this i cant find any specifics on this.

i was using adminlte as an example but for that the plugins only use the data that is being displayed in the data-tables

Laravel 11 @yield not displaying

I am trying to use the @yield directive in my blade view to display content.
I’ve followed the Laravel documentation but it is simply not displaying my content.

resources/views/layouts/home.blade.php

...
<body>
    @yield('content')
</body>
...

resources/views/layouts/content.blade.php

@extends('home')
@section('content')
<p>This is my content</p>
@endsection

Both blade views are in the same folder.
If I use the @include directive it does work, but that’s not what I’m after.
Thanks.

Why isn’t my email interpreting my code and displaying the raw code?

I want to send an email with Laravel, for that, no problem, the email is sent. However, the email I want to send includes two tables that I want to show to the user. Once the email is received, half of it is “illegible”. Only the first painting is interpreted, the second is shown in its raw form.

Here is my blade view.

<!-- resources/views/emails/visite/answer.blade.php -->
@component('mail::message')

@lang('Hello'),<br/><br/>

Votre demande de visite planifiée datant du {{ date('d/m/Y', strtotime($planif->created_at)) }} a été @if($planif->etat == 1) acceptée. @else refusée. @endif

@if($planif->etat == 1)
    @component('mail::table')
    | Nom       | Prénom    | Société     |
    |-----------|-----------|-------------|
    @foreach(json_decode($planif->final_visiteurs) as $item)
    | {{ $item->name }} | {{ $item->firstname }} | {{ $item->societe }} |
    @endforeach
    @endcomponent

    <br/><br/>

    @component('mail::table')
    | Modèle        | Immatriculation  |
    |---------------|------------------|
    @foreach(json_decode($planif->final_vehicules) as $item)
    | @if($item->modele != null) {{ $item->modele }} @else Non renseigné @endif | {{ $item->immat }} |
    @endforeach
    @endcomponent
@endif

Pour plus d'informations, veuillez contacter l'ASIP.

@lang('Sincerely yours')<br>
EamusCork
@endcomponent

Here is the function that sends the email.

public function accept_planif(Request $request, $id){
        $planif = PlanificationVisite::findOrFail($id);

        $vis_final = [];
        if($request->input('vis')){
            $vis = json_decode($request->input('vis')[0]);
            for($i = 0; $i < count($vis); $i++){
                $vis_final[] = [
                    'name' => $vis[$i]->name,
                    'firstname' => $vis[$i]->firstname,
                    'societe' => $vis[$i]->societe,
                    'document' => $vis[$i]->document
                ];
            }
        }

        $veh_final = [];
        if($request->input('veh')){
            $veh = json_decode($request->input('veh')[0]);
            for($i = 0; $i < count($veh); $i++){
                $veh_final[] = [
                    'grise' => $veh[0]->grise,
                    'immat' => $veh[0]->immat,
                    'modele' => $veh[0]->modele,
                ];
            }
        }

        $planif->update(['final_visiteurs' => json_encode($vis_final), 'final_vehicules' => json_encode($veh_final), 'etat' => 1]);

        $email = new AnswerPlanificationVisite($planif);
        Mail::to($planif->email_sent)->locale('fr')->send($email);

        return redirect()->route('visite.see_planif');
    }

This is how the email is rendered.
enter image description here

I tried to modify the blade view directly using the <table>, <thead>, <tbody>… tags without success. As you can see, the components don’t work any better. I checked the documentation for the use of “Mail”, I don’t think I made an error on the sending function and I use markdown correctly.

Cannot install Composer on my MacBook Air M2

I aleady install the xampp and it’s work
i print the “hello world” on the localhost and it’s work

But when install the composer
(
php -r “copy(‘https://getcomposer.org/installer’, ‘composer-setup.php’);”

The Result is (zsh: command not found: php) for all the lines

php -r “if (hash_file(‘sha384’, ‘composer-setup.php’) === ‘dac665fdc30fdd8ec78b38b9800061b4150413ff2e3b6f88543c636f7cd84f6db9189d43a81e5503cda447da73c7e5b6’) { echo ‘Installer verified’; } else { echo ‘Installer corrupt’; unlink(‘composer-setup.php’); } echo PHP_EOL;”

The Result is (zsh: command not found: php) for all the lines

php composer-setup.php

The Result is (zsh: command not found: php) for all the lines

php -r “unlink(‘composer-setup.php’);”

The Result is (zsh: command not found: php) for all the lines

)

what the solution for this problem please, I try to install the homebrew but it was not installed also, i don’t know what the issue

Can’t load objects through JFactory

Pretty new here.
I’ve used this code:

$db = JFactory::getDbo();
$query = $db->getQuery(true);

$query
->select($db->quoteName(array('k.*', 'u.*')))
->from($db->quoteName('vm_kampe', 'k'))
->join('INNER', $db->quoteName('vm_kuponer', 'u') . ' ON (' . $db->quoteName('k.id') . ' = ' . $db->quoteName('u.id') . ')')
->where($db->quoteName('u.uid') . ' LIKE ' . $db->quote($bruger) . ' AND ' . $db->quoteName('u.liga') . ' LIKE ' . $db->quote('tip3'))
->order('k.rkf ASC');

$db->setQuery($query);

$results = $db->loadObjectList();

Everything works fine until last line ($results). Then it shows error 1054. I’m using an ooooold version of Joomla (3.10) as I haven’t worked in joomla in a long time and not sure I can learn the new versions 😀 Sorry!

I tried what I could. The site worked in 2018 but now it shows error.

How to use yahoo! JAPAN Japanese Language Processing API

I need to add a feature called Kanji to Kana converter to my WordPress website. I’m using the Code Snippets plugin to inject scripts into my site.

After researching for a whole night, I found a free API (Yahoo! JAPAN Japanese Language Processing API).

Here is the documentation page for that API: API Documentation.

I don’t know what to do next.

Looking for a solution. Thanks in advance.

I asked ChatGPT for assistance, and it provided me with a PHP code snippet to inject through the Code Snippets plugin. Here is the code I received:

function kanji_to_kana_converter($query) {
    $appId = 'your-client-id';
    $url = 'https://jlp.yahooapis.jp/JIMService/V2/conversion';

    $params = json_encode([
        'id' => '1234-1',
        'jsonrpc' => '2.0',
        'method' => 'jlp.jimservice.conversion',
        'params' => [
            'q' => $query,
            'format' => 'hiragana',
            'mode' => 'kanakanji',
            'option' => ['hiragana', 'katakana', 'alphanumeric', 'half_katakana', 'half_alphanumeric'],
            'dictionary' => ['base', 'name', 'place', 'zip', 'symbol'],
            'results' => 999
        ]
    ]);

    $args = [
        'body'        => $params,
        'headers'     => [
            'Content-Type' => 'application/json',
            'User-Agent'   => 'Yahoo AppID: ' . $appId,
        ],
        'method'      => 'POST',
    ];

    $response = wp_remote_post($url, $args);

    if (is_wp_error($response)) {
        return 'Request failed';
    }

    $body = wp_remote_retrieve_body($response);
    return json_decode($body, true);
}

function display_converter_shortcode($atts) {
    $atts = shortcode_atts(['query' => ''], $atts, 'kanji_to_kana');
    $result = kanji_to_kana_converter($atts['query']);
    return '<pre>' . print_r($result, true) . '</pre>';
}
add_shortcode('kanji_to_kana', 'display_converter_shortcode');

I expected this code to allow users to enter Kanji text and receive the Kana conversion directly on my website using a shortcode. However, I have not been able to get it to work. The page either shows nothing or does not execute the expected functionality.

Could someone guide me on what might be going wrong and how to correctly implement this feature?

How to speed up users query in WordPress?

I have created a plugin where employers are able to search freelancers and hire them. Freelancer can select dates from a calendar to mark those dates as available to work.

enter image description here

Employers search between dates (from and to) to see the available freelancers then they can shortlist or send job brief to them.

The problem is when employer select two dates which has many days gap, the query just goes on time out.

I have tried adding availability dates into user_meta as an array then queried as following but its obvious that gap of many days will have time out problem as I was using LIKE.

$date_query = array();

if ( ! empty( $from ) && ! empty( $to ) ) {

  $start = new DateTime( $from );
  $end = new DateTime( $to );
  $end = $end->modify( '+1 day' ); // Include the end date in the period
  $interval = new DateInterval( 'P1D' ); // 1 Day interval
  $date_range = new DatePeriod( $start, $interval ,$end );
  $date_query = [ 'relation' => 'AND' ];

  foreach( $date_range as $date ) {

    $date_query[] = array(
      'key' => 'fmaa_available_dates',
      'value' => $date->format( 'Y-m-d' ),
      'compare' => 'LIKE'
    );

  }

}

I also tried to add them into separate user meta using add_user_meta() but that also caused the same problem as the query goes too long for having a lot of days.

if ( ! empty( $from ) && ! empty( $to ) ) {

  $start = new DateTime( $from );
  $end = new DateTime( $to );
  $end = $end->modify( '+1 day' ); // Include the end date in the period
  $interval = new DateInterval( 'P1D' ); // 1 Day interval
  $date_range = new DatePeriod( $start, $interval ,$end );
  $date_query = [ 'relation' => 'AND' ];

  foreach ( $date_range as $date ) {

    $date_query[] = array(
      'key' => 'fmaa_availability_dates',
      'value' => $date->format( 'Y-m-d' ),
      'compare' => 'IN'
    );

  }

}

HTTP ERROR 500 on Laravel Vite 11 when Deploy to Shared Hosting

I use 000Webhost as my web-shared hosting.

My folder structure looks like this:

I’ve changed my Composer Autoloader directory and this is my index.php looks like:

<?php

use IlluminateHttpRequest;

define('LARAVEL_START', microtime(true));

// Determine if the application is in maintenance mode...
if (file_exists($maintenance = __DIR__.'/../laravel/storage/framework/maintenance.php')) {
    require $maintenance;
}

// Register the Composer autoloader...
require __DIR__.'/../laravel/vendor/autoload.php';

// Bootstrap Laravel and handle the request...
(require_once __DIR__.'/../laravel/bootstrap/app.php')
    ->handleRequest(Request::capture());

I use sqlite and local storage for my database, This is my .env.

APP_NAME=Laravel
APP_ENV=local
APP_KEY=mykey
APP_DEBUG=true
APP_TIMEZONE=UTC
APP_URL=http://localhost

APP_LOCALE=en
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=en_US

APP_MAINTENANCE_DRIVER=file
APP_MAINTENANCE_STORE=database

BCRYPT_ROUNDS=12

LOG_CHANNEL=stack
LOG_STACK=single
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug

DB_CONNECTION=sqlite
# DB_HOST=127.0.0.1
# DB_PORT=3306
# DB_DATABASE=laravel
# DB_USERNAME=root
# DB_PASSWORD=

SESSION_DRIVER=database
SESSION_LIFETIME=120
SESSION_ENCRYPT=false
SESSION_PATH=/
SESSION_DOMAIN=null

BROADCAST_CONNECTION=log
FILESYSTEM_DISK=local
QUEUE_CONNECTION=database

CACHE_STORE=database
CACHE_PREFIX=

MEMCACHED_HOST=127.0.0.1

REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_MAILER=log
MAIL_HOST=127.0.0.1
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="[email protected]"
MAIL_FROM_NAME="${APP_NAME}"

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false

VITE_APP_NAME="${APP_NAME}"

Do i need to run “php artisan run build” first? and do i need to move my css, js, views folders from resources to public folder?

did i miss something? anything would help, thanks in advance

HTML output dont break page

I have a problem with HTML output
problem in line 5 first code (i must write an empty string WriteHTML(”) )
problem in body file line 3 (AddPage doesn’t work)

   self::init($param);
   ob_start();
   include $path . '/index.pdf.php';
   $output = ob_get_clean();
   self::$mpdf->WriteHTML(''); // this line must be exist Otherwise doesn't work
   self::$mpdf->WriteHTML($output);
   return self::$mpdf->Output($param['fileName'] . '.pdf', self::$dest);

and the index file :

<?php
include __DIR__ . '/header.pdf.php';
include $path . '/' . $body . '.pdf.php';
include $path . '/footer.pdf.php';

the body file :

<?php
echo 'A';
PDFHTML::addPageBreak(); //the only way to do a page break
self::$mpdf->AddPage(); //This line doesn't work
echo 'B';

i try to resolve the bug in my code source

Understanding Session Management in Symfony 6.4

I’m working on a project using Symfony 6.4 and I would like to better understand how sessions work in this version of the framework. I have some experience with older versions of Symfony, but I’m not sure if there are significant changes or improvements in session management in Symfony 6.4.

My specific questions are:

How does Symfony 6.4 initialize and manage sessions?

What are the basic steps to start and manage a session in Symfony 6.4?
What configuration options are available for sessions in Symfony 6.4?

Are there any new or changed configuration parameters I should be aware of?
How can I store and retrieve data from a session?

What are the recommended methods for storing and retrieving data within a session in Symfony 6.4?
Are there any security aspects I should consider when using sessions in Symfony 6.4?

What are the best practices to ensure session security?
How can I implement custom session storage mechanisms?

Are there specific interfaces or classes I need to implement or extend to use a custom session storage mechanism?
An example code or link to relevant documentation would also be very helpful.

Thanks for your help!

I tried using the Symfony documentation to create a better sentence.

AWS Linux 2023 install php 7.2

I want to create a dockerfile in AL2023 and install PHP 7.2. Because AL2023 doesn’t support EPEL, I use remi.

RUN rpm -Uvh https://rpms.remirepo.net/enterprise/remi-release-7.rpm && yum -y update

But I got the error message as follwing.

“Problem: conflicting requests

  • nothing provides epel-release = 7 needed by remi-release-7.9-6.el7.remi.noarch from @commandline
  • nothing provides redhat-release needed by remi-release-7.9-6.el7.remi.noarch from @commandline”

Could anyone help me to solve this problem? Thanks.

assertDatabaseHas fails when used with decimal database column

I have a table with a quantity column, defined as DECIMAL(8,3).

I wrote a test that creates a record in the table and tests if the record is present:

$this->assertDatabaseHas('my_table', [
    'id' => $newRecord->getKey(),
    'id_user' => $id_user,
    'quantity' => (float)$quantity,
    'id_action' => 5,
]);

This is the result of the test:

Failed asserting that a row in the table [my_table] matches the attributes {
    "id_user": 6166,
    "quantity": 10,
    "id_action": 5,
    "params": "{"id_sale_bid":2040}"
}.

Found similar results: [
    {
        "id_user": 6166,
        "quantity": "10.000",
        "id_action": 5,
        "params": "{"id_sale_bid": 2040}"
    }
]

As you can see the record is present, it’s just that it looks for the wrong type.

When I refresh the page my table style is not applied

I’m trying to create a table. When I click on the “generate” button, it inserts rows with data such as page title, date, actions…
The problem is that when I click it, it generates the rows with the style I’ve added. But when I refresh the page, the style is no longer applied.

  public function woosterPartnerPluginSection()
    {
?>
        <section class="presentation-content">
            <?php
            do_settings_sections('wooster_gutenberg');
            ?>
            <h2>Générateurs de page</h2>
            <p>Choissisez le constructeur de page que vous préférez : </p> <?php
            do_settings_sections('wooster_form');
            // Conditionally display the buttons based on the presence and activation of Elementor plugin
            if ($this->ispluginElementorActive()) {
            ?>
            <!-- Display the buttons for both Gutenberg and Elementor -->
                <div style="display: flex;">
                    <form method="POST" action="">
                        <input type="hidden" name="submit-gutenberg" value="Gutenberg">
                        <input type="image" id="gutenberg_button" src="<?php echo plugins_url('assets/img/Gutenberg.png', __FILE__); ?>" alt="Gutenberg" width=100% height=100% />
                    </form>
                    <form method="POST" action="">
                        <input type="hidden" name="submit-elementor" value="Elementor">
                        <input type="image" id="elementor_button" src="<?php echo plugins_url('assets/img/Elementor.png', __FILE__); ?>" width=100% height=100% />
                    </form>
                </div>

            <?php } else { ?>
                <div style="display: flex;">
                    <form method="POST" action="">
                        <input type="hidden" name="submit-gutenberg" value="Gutenberg">
                        <input type="image" id="gutenberg_button" src="<?php echo plugins_url('assets/img/Gutenberg.png', __FILE__); ?>" width=100% height=100% />
                    </form>
                </div>
            <?php
            }
            ?>

        <div class="results-info">
        <?php
            $generated_pages = get_option('wooster_generated_pages', array());
            $num_generated_pages = count($generated_pages);
            echo 'Nombre de résultats : ' . $num_generated_pages;
        ?>
        </div>
        <div id="notification" class="notification">
            Page générée avec succès
        <table class="custom-table">
            <thead>
                <tr>
                <th scope="col" id="date" class="manage-column column-date">Titre</th>
                    <th scope="col" id="date" class="manage-column column-author">Date</th>
                    <th scope="col" id="constructor" class="manage-column column-author">Constructeur</th>
                    <th scope="col" id="actions" class="manage-column column-actions">Actions</th>
                </tr>
            </thead>
            <tbody id="generated-pages">
            </tbody>
        </table>
                <script>
                    document.addEventListener('DOMContentLoaded', (event) => {
                        function updatePageWithNewPost(data, buttonValue, postId) {
                            const tableRow = document.createElement('tr');
                            tableRow.id = 'post-' + data.id;
                            tableRow.classList.add('custom-table-row');

                            const titleCell = document.createElement('td');
                            titleCell.textContent = data.title;

                            const constructorCell = document.createElement('td');
                            constructorCell.textContent = buttonValue;

                            const dateCell = document.createElement('td');
                            dateCell.textContent = data.date;

                            const actionsCell = document.createElement('td');
                            actionsCell.classList.add('actions');



                            const viewButton = document.createElement('button');
                            viewButton.classList.add('viewBtn');
                            viewButton.innerHTML = '<i class="fas fa-eye fa-lg"></i>';
                            viewButton.dataset.previewUrl = data.previewUrl;

                            viewButton.addEventListener('click', () => {
                                const previewUrl = viewButton.dataset.previewUrl;
                                window.location.href = previewUrl;
                            });

                            actionsCell.appendChild(viewButton);

                            const editButton = document.createElement('button');
                            editButton.classList.add('editBtn');
                            editButton.innerHTML = '<i class="fas fa-edit fa-lg"></i>';
                            editButton.addEventListener('click', () => {
                                const editUrl = '<?php echo admin_url('post.php?action=edit&post='); ?>' + data.id;
                                window.location.href = editUrl;
                            });

                            const deleteButton = document.createElement('button');
                            deleteButton.classList.add('deleteBtn');
                            deleteButton.innerHTML = '<i class="fas fa-trash-alt fa-lg"></i>';
                            deleteButton.dataset.postId = data.id;

                            deleteButton.addEventListener('click', function() {
                                const postId = this.dataset.postId;
                                const rowToDelete = this.closest('tr');

                                if (confirm('Êtes-vous sûr de vouloir supprimer ce post ?')) {
                                    fetch('<?php echo admin_url('admin-ajax.php'); ?>', {
                                            method: 'POST',
                                            headers: {
                                                'Content-Type': 'application/x-www-form-urlencoded',
                                            },
                                            body: 'action=delete_post&id=' + postId,
                                        })
                                        .then(response => response.json())
                                        .then(data => {
                                            if (data.success) {
                                                rowToDelete.remove();
                                            } else {
                                                console.error('Erreur lors de la suppression du post');
                                            }
                                        })
                                        .catch(error => {
                                            console.error('Erreur:', error);
                                        });
                                }
                            });

                            actionsCell.appendChild(viewButton);
                            actionsCell.appendChild(editButton);
                            actionsCell.appendChild(deleteButton);

                            tableRow.appendChild(titleCell);
                            tableRow.appendChild(dateCell);
                            tableRow.appendChild(constructorCell);
                            tableRow.appendChild(actionsCell);

                            document.getElementById('generated-pages').appendChild(tableRow);
                            // const tableBody = document.getElementById('generated-pages');
                            // tableBody.appendChild(tableRow);

                        }

                        const gutenbergButton = document.getElementById('gutenberg_button');
                        const elementorButton = document.getElementById('elementor_button');

                        const gutenbergForm = gutenbergButton.closest('form');
                        const elementorForm = elementorButton.closest('form');

                        const forms = [gutenbergForm, elementorForm];

                        forms.forEach(form => {
                            form.addEventListener('submit', function(e) {
                                e.preventDefault();
                                const buttonValue = form.querySelector('[type="hidden"]').value;
                                const formData = new FormData(form);
                                formData.append('action', 'create_post');

                                fetch('<?php echo admin_url('admin-ajax.php'); ?>', {
                                        method: 'POST',
                                        body: formData
                                    })
                                    .then(response => response.json())
                                    .then(data => {
                                        updatePageWithNewPost(data, buttonValue, data.id);
                                        posts.push(data);
                                        showNotification();

                                    });

                            });
                        });

to add the element , I use a loop and display all the data from $generated_pages. This is the row:

    public function display_generated_pages()
    {
        $generated_pages = get_option('wooster_generated_pages', array());
        $updated_pages = array();

        foreach ($generated_pages as $page) {
            $post = get_post($page['id']);
            if ($post) {
            if ($post && ($post->post_status == 'draft' || $post->post_status == 'publish')) {

                echo '<tr id="post-' . esc_attr($page['id']) . '" class="custom-table-row">';
                echo '<td>' . esc_html($page['title']) . '</td>';
                echo '<td>' . esc_html($page['title']) . '</td>';
                echo '<td>' . esc_html($page['date']) . '</td>';
                $constructor = '';
                if (isset($_POST['submit-gutenberg']) && $_POST['submit-gutenberg'] === 'Gutenberg') {
                    $constructor = 'Gutenberg';
                } elseif (isset($_POST['submit-elementor']) && $_POST['submit-elementor'] === 'Elementor') {
                    $constructor = 'Elementor';
                }
                echo '<td>' . esc_html($constructor) . '</td>';
                echo '<td class="actions">';
                echo '<button class="viewBtn" data-preview-url="' . esc_url($page['previewUrl']) . '"><i class="fas fa-eye fa-lg"></i></button>';
                echo '<button class="editBtn"><i class="fas fa-edit fa-lg"></i></button>';
                echo '<button class="deleteBtn" data-post-id="' . esc_attr($page['id']) . '"><i class="fas fa-trash-alt fa-lg"></i></button>';
                echo '</td>';
                echo '</tr>';



                // Ajoutez la page existante à la liste mise à jour
                $updated_pages[] = $page;
            } elseif ($post->post_status != 'trash') {
                $updated_pages[] = $page;
            }
            }
        }

        // Mettez à jour l'option avec la liste des pages existantes
        update_option('wooster_generated_pages', $updated_pages);
    }

mytable