Opencart'da "Error while sending QUERY packet. PID=" Hatası ve Çözümü


PHP Warning:  Error while sending QUERY packet. PID=29811 in /public_html/system/library/db/mpdo.php on line 57 gibi bir hata alıyorsanız bunun nedeni sorgulamalarınızın izin verilen maksimum değeri geçmesi olabilir. 

Bu hatanın çözümü için, ilgili dosyaya (system/library/db/mpdo.php) aşağıdaki satırı eklemenizi öneririm:
$this->connection->exec("SET GLOBAL max_allowed_packet=524288000");

Ben bu şekilde sorunu çözdüm. Kodu eklediğinizde aşağıdaki gibi olacaktır:

public function __construct($hostname, $username, $password, $database, $port = '3306') {
    try {
        $this->connection = new \PDO("mysql:host=" . $hostname . ";port=" . $port . ";dbname=" . $database, $username, $password, array(\PDO::ATTR_PERSISTENT => true));
    } catch(\PDOException $e) {
        throw new \Exception('Failed to connect to database. Reason: \'' . $e->getMessage() . '\'');
    }

    $this->connection->exec("SET NAMES 'utf8'");
    $this->connection->exec("SET CHARACTER SET utf8");
    $this->connection->exec("SET CHARACTER_SET_CONNECTION=utf8");
    $this->connection->exec("SET SQL_MODE = ''");
    $this->connection->exec("SET GLOBAL max_allowed_packet=524288000");
}


Opencart Ajax Filter by Dreamvention


Opencart standart yapısında kullanılışlı bir filtreleme maalesef bulunmuyor. Ajax yani sayfa yenilenmeden filtreleme yapabileceğiniz ücretsiz bir eklenti arıyorsanız Dreamvention tarafından yayınlanan Ajax Filter Free eklentisini öneririm:

MODÜL İÇİN TAVSİYE ETTİĞİM AYARLAR:
Aşağıdaki ayarlar tavsiye niteliğindedir fakat bazı ayarlar modülün çalışmasını direk etkilediği için önemlidir.







GÖRDÜĞÜM HATALAR ve ÇÖZÜMLERİ:

Buradan sonra yazacaklarım Opencart 2.3.0.2 versiyonu ve eklentisi için geçerlidir, diğer versiyonlarda benzer sorunlar mevcut ise uygulayabilirsiniz. 

Sorun 1: Bir kategori sayfasını açtınız diyelim ve hiç beklemeden menüden başka bir kategoriye tıkladınız. Bu durumda hala ilk tıkladığınız kategorinin ürünlerini görmeye devam ediyorsanız, bunun nedeni Ajax Filter eklentisinin veritabanındaki TEMP tablodan işlem yapmasıdır. Arada az zaman geçtiği için hala eski sorgudaki ürünleri listelemektedir.

Çözüm: Eklentiyi indirip kurduktan sonra aşağıdaki kodları bir xml dosyası olarak kaydedip vqmod/xml klasörünüze ekleyiniz. Vqmod kullanmıyorsanız ilgili dosyalardan bu değişiklikleri manuel olarak yapabilirsiniz. Burada HTTP_USER_AGENT hatası ile ilgili ek olarak bir düzeltme daha var, onu da eklemenizi tavsiye ederim.
  <file path="catalog/controller/extension/module/d_ajax_filter.php">
  <operation info="HTTP_USER_AGENT error">
      <search><![CDATA[if (preg_match('/(iPhone|iPod|iPad|Android|Windows Phone)/', $this->request->server['HTTP_USER_AGENT'])) {]]></search>
      <add position="replace"><![CDATA[
      if ( isset($this->request->server['HTTP_USER_AGENT']) && preg_match('/(iPhone|iPod|iPad|Android|Windows Phone)/', $this->request->server['HTTP_USER_AGENT']) ) {
      ]]></add>
  </operation>
  </file>
  <file path="catalog/model/extension/module/d_ajax_filter.php">
  <operation info="fix temp database">
      <search><![CDATA[$this->db->query($sql);]]></search>
      <add position="before" index="1"><![CDATA[
      $this->db->query("DROP TEMPORARY TABLE IF EXISTS `".DB_PREFIX."af_temporary`");
      ]]></add>
  </operation>
  </file>

Sorun 2: "Kurdum, ayarlamaları yaptım, fakat ajax mode çalışmıyor. Yani filtreleme yaptığımda hiçbir değişiklik olmuyor." diyorsanız bunun nedeni muhtemelen modülün ayarlarında bulunan Content Path'in doğru girilmemesidir. Burada bir jquery seçici girilmiştir. Fakat sizin temanıza ait kategori listeleme sayfasında bu id'ye sahip bir div elemanı bulunmadığı için ajax modu çalışmamaktadır.

Çözüm: Kendi temanıza ait kategori listeleme sayfasını açın ve <div id="content"> elemanından sonra gelen ilk div'e ait id'yi bulup buraya girin. Bu düzenlemeyi yukarıdaki modül ayarlarına ait resimlerde görebilirsiniz.

PHP Fonksiyonu Çağıran Sayfa Bilgilerini Almak

debug_backtrace()

Php'de fonksiyon ve metodlar çeşitli sayfalardan çağrılabilir. Bir hata durumunda metoda parametre gönderen sayfayı görmek isteyebilirsiniz. Bu gibi hata ayıklama durumlarında kullanabileceğiniz debug_backtrace fonksiyonu için aşağıdaki kodu kullanabilirsiniz.

$trace = debug_backtrace();
$caller = array(
    "file" => $trace[1]['file'],
    "line" => $trace[1]['line'],
    "function" => $trace[1]['function'],
    "class" => $trace[1]['class'],
);
var_dump( $caller );

ÖNEMLİ NOT: Burada dikkat etmeniz gereken husus; direk olarak var_dump( debug_backtrace() ) şeklinde kullanarak bütün sonucu bastırmamanızdır. Projenize göre değişmekle birlikte MB'larca bir sonuç döndürebilir. Bu nedenle dizideki 4 değeri çıktı olarak almanızı öneririm.

var_dump yerine error dosyasına yazdırmak için var_error_log($caller) kullanabilirsiniz.

CSS Opacity Kullanımı - Tüm Tarayıcılar


CSS Opacity - All Browsers

Eğer çok eski tarayıcıları desteklesin gibi bir derdiniz yoksa kısaca şu 3 satır işinizi görecektir. Tavsiye edilen kullanımdır. zoom ve filter komutları IE içindir (başımızın belası:))
zoom: 1;
filter: alpha(opacity=85);
opacity: 0.85;

Eğer önemli bir projeniz var ve tüm tarayıcılarda sorunsuz görünmesi gerekiyorsa (en eski tarayıcılarda dahi) o zaman bu uzun versiyonu kullanmanız tavsiye edilir.
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=85)"; /* IE 8 */
filter: alpha(opacity=85);  /* IE 5-7 */
-moz-opacity: 0.85; /* Netscape */
-khtml-opacity: 0.85; /* Safari 1.x */
opacity: 0.85; /* Good browsers */

Opencart PHP Zip & Download (Ajax Method)


Opencart sayfasındaki bir butona tıklayarak dosyaları indirmek için ajax metodunu kullanabilirsiniz. Bunun için controller ve view dosyalarına ekleyeceğiniz kodlar aşağıdadır.

Controller:
public function downloadAllFiles() {
    $json = array();

    $zip_files = array(
        "file-1.jpg",
        "file-2.jpg",
        "file-3.jpg",
    );
    
    if ( count($zip_files) > 0 ) {
        $zipname = "indir.zip";
        $zip = new ZipArchive;
        $zip->open($_SERVER['DOCUMENT_ROOT']."/store/image/download/".$zipname, ZipArchive::CREATE);
        foreach ($zip_files as $file) {
          $zip->addFile($_SERVER['DOCUMENT_ROOT']."/store/image/download/".$file, $file);
        }
        $zip->close();

        //success and send zip file path
        $json['success'] = 'https://example.com/store/image/download/'.$zipname;
        $this->response->addHeader('Content-Type: application/json');
        $this->response->setOutput(json_encode($json));
    }
    else {
        $json['error'] = "İndirilecek dosya bulunamadı! Lütfen kontrol ediniz.";
        $this->response->addHeader('Content-Type: application/json');
        $this->response->setOutput(json_encode($json));
    }
}

View:
<!-- Add Download Button -->
<button id="btn-download-zip" data-loading-text="<?php echo $text_downloading; ?>" class="btn btn-info"><?php echo $text_download; ?> <i class="fa fa-download"></i></button>

<!-- Add Ajax Script -->
<script type="text/javascript">
    $(document).delegate('#btn-download-zip', 'click', function() {
        $.ajax({
            url: 'index.php?route=sale/order/downloadallfiles',
            type: 'post',
            dataType: 'json',
            beforeSend: function() {
                $('#btn-download-zip').button('loading');
            },
            complete: function() {
                $('#btn-download-zip').button('reset');
            },
            success: function(json) {
                $('.alert').remove();

                if (json['error']) {
                    $('#content > .container-fluid').prepend('<div class="alert alert-danger"><i class="fa fa-exclamation-circle"></i> ' + json['error'] + '</div>');
                }
                else {
                    //download zip file
                    window.location.href = json['success'];
                }
            },
            error: function(xhr, ajaxOptions, thrownError) {
                alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
            }
        });
    });
</script>

2020 En İyi Wordpress Eklentileri



2020 En İyi Wordpress Eklentileri | 2020 Best Wordpress Plugins
Son Güncelleme | Last Update: 1.12.2020

  • Bir çok eklenti arasından en kullanılışlı gördüklerimi (en çok indirilenleri değil) sizlerle paylaşacağım. 
  • Hepsini kullandım ve sizlere öneriyorum. Genelde pro veya premium kısıtlaması olmayan tamamen ücretsiz eklentileri seçtim. 
  • Kullanım amaçlarına göre listeleyeceğim. 
  • Yazılan eklenti adlarını kopyalayıp Admin > Plugins > Add New tıklayarak aratınız.

KULLANIM AMAÇLARINA GÖRE EKLENTİLER

Wordpress üyelik sistemini ve sayfalarını düzenleme
User Registration WPEverest
Simgesi laleye benzeyen bu eklenti, standart accounts, login, register, forgot password vs gibi üyelik sayfalarını özelleştirmenizi sağlayacaktır. Kendi üye kayıt formunuzu oluşturmanıza imkan vermektedir ki bu benzerleri arasından bu eklentiyi tercih sebebim oldu. Dökümantasyon sayfası kurulumda size yardımcı olacaktır.

Wordpress sayfaları veya sayfa içeriklerini üyelere özel yaparak gizleme
Private Content Aldo Latino
Örneğin bir sayfanız var ve üye olmayanlar sadece bir mesaj görsün ve giriş yapmaya yönlendirilsin istiyorsunuz, üye olanlar ise bu sayfa içeriğini görebilsin istiyorsunuz. İşte bu durumda işinize yarayacak short code desteği olan bir eklentidir. Aslında bütün özellikleri short code olarak çalışıyor desek daha doğru olacak. github sayfası kurulumdan sonra size yardımcı olacaktır.

Wordpress eklentilerini farklı dillere çevirme
Loco Translate
Kullandığınız bir eklentinin Türkçe desteği yoksa bu eklenti tam size göre. Plugin translate deyince ilk akla gelen ve en kapsamlı eklenti gördüğü kadarıyla. Fakat ilk denemenizde işe yaramadı çevirmedi gibi düşünmeyin. 1) Öncelikle çevirmek istediğiniz eklentiyi listeden seçin. 2) New language butonuna tıklayın ve burdan wp genel ayarlar sekmenizde seçili olan sistem diliniz ne ise onu seçin (burası önemli!). 3) Yine önemli olan diğer kısım location kısmı yani dil dosyasının nereye ekleneceği. Burda 3 farklı yöntem var. Ben burda languages/loco/plugins/ornek-plugin-tr_TR.po yolunu seçtim. 4) Çeviri yapacağınız ifadeyi aratın ve alta seçtiğiniz dildeki tercümesini ekleyin ve kaydedin. 5) Bu eklentiyi kullandığınız sayfayı/postu update yapın (bunu yapmayınca çeviri aktif olmayabiliyor). 6) Yine de olmazsa mevcut çeviri dosyasını silip, 3. aşamada söylediğim diğer iki location için işlemleri tekrarlayın.

Wordpress sayfalarında sağ tuş ve içerik kopyalanmasını engelleme
WP Content Copy Protection with Color Design
Sayfalarınnızda sağ tuşa tıklanmasını ve içerik kopyalanmasını (seçerek, ctrl+a, vs) engellemek istiyorsanız bu eklentiyi kullanabilirsiniz. Sağ tuşa tıklandığında editlenebilir bir uyarı mesajı çıkması ve belirli sayfa/postlar için bu engellemeyi yapabilmesi bu eklentiyi benzerlerinden öne çıkarmaktadır.

    Wordpress sayfalarına css veya js kodları ekleme
    Simple Custom CSS and JS
    Bu eklenti ile sayfaların header veya footer kısmına js, css veya html kodları ekleyebilmektesiniz. Bu tarzda farklı eklentiler var fakat sağlıklı çalışmıyor, bu eklenti sağlıklı bir şekilde çalışmaktadır.

     

    Wordpress Çıkış Sonrası Onay İsteminin Kapatılması

    Wordpress Bypass Logout Confirmation 

    Kullanıcı çıkış yaptığında gelen "Çıkmak istiyor musunuz?" benzeri bir soruyu almadan direk çıkış yapmak istiyorsanız, aşağıdaki kodu functions.php içerisine ekleyin. Böylece çıkış butonuna tıkladıktan sonra oturumunuz sonlanacak ve direk anasayfaya yönlendirileceksiniz.

    /**
     * Generates custom logout URL
     */
    function getLogoutUrl($redirectUrl = ''){
        if(!$redirectUrl) $redirectUrl = site_url();
        $return = str_replace("&amp;", '&', wp_logout_url($redirectUrl));
        return $return;
    }
    /**
     * Bypass logout confirmation on nonce verification failure
     */
    function logout_without_confirmation($action, $result){
        if(!$result && ($action == 'log-out')){ 
            wp_safe_redirect(getLogoutUrl()); 
            exit(); 
        }
    }
    add_action( 'check_admin_referer', 'logout_without_confirmation', 1, 2);