Nasıl Yapılır

Drupal 8 ile Özel Modul Geliştirme (Oluşturma)

Drupal 8 ile Özel Modul Geliştirme (Oluşturma)

Birlikte ilk özel drupal 8 modülümüzü oluşturalım

Drupal 8 (neredeyse) burada ve bir geliştiriciyseniz, artık Drupal 8 modül geliştirme öğrenmeye başlamanın zamanı geldi. Drupal 8'deki modül geliştirme, Drupal 7'den büyük bir değişime işaret ediyor. Bu, Drupal 8 geliştirme öğrenme sürecinde ilerleyeceğim bir dizi ilk öğreticidir. Bu derste oluşturduğumuz modül, olduğu kadar basittir ve modül yapısına bir fikir edinmenize yardımcı olmayı amaçlamaktadır.

Başlamadan önce, Drupal 7 modül geliştirme ile bazı önemli farklılıklara değineceğiz. Aşağıda, bu öğreticide kullanılacak kavramların listesi verilmiştir:

  • Drupal 8 nesneye () yöneliktir ve Drupal 7 öncelikle usule uygundur. Bu, kodunuzun birçoğunun artık basit işlevler yerine sınıflarda olacağı anlamına geliyor. Birçokları için çok zor olacak, ancak kesinlikle modül geliştirme daha esnek olacak ve süreçlerinizde yeteneklerinizi modern programlama uygulamasına geçireceksiniz
  • Her sınıfın bir ad alanına ihtiyacı olacaktır. Ad boşluğu, sınıfınızın aynı adlı başka bir sınıfla çakışmamasına dikkat edin. Bir dosya sisteminde bir dizin gibi düşünebilirsiniz. Farklı dizinlerde aynı adı taşıyan iki dosyaya sahip olabilirsiniz.
  • Drupal harici kütüphaneleri kullanır ve genişletir
  • Drupal 8, .info dosyaları yerine .yml dosyalarını kullanır. .yml dosyaları menü öğelerini, sekmeleri vb. tanımlamak için de kullanılır.
  • Bir URL'yi geri arama işlevine eşlemek için hook_menu () kullanmanız gerekmez. Bu artık bir menü sınıfı ve bir rota tarafından halledilir.
  • Drupal 8, değiştirilebilir işlevsellik parçaları sağlayan eklentileri kullanır. Eklentiler hakkında daha fazla bilgi için - Joe Shindelar'ın Drupalize.me 'deki açıklamasına göz atın.
  • Drupal 8, PHP ek açıklamalarını kullanır. Ek açıklamalar PHP yorumlarını içeriyor ve bir sınıf hakkında hayati bilgiler içeriyor. Drupal 8 eklenti sistemi bunları eklentileri tanımlamak için kullanır ve eklentinizi keşfetmek için Drupal tarafından kullanılırlar.

Not: Bu öğreticide yazılmış olan bir çok kod, generate:module, generate:controller ve generate:plugin: block komutlarını (İpucu için teşekkürler, Jesus Manuel Olivas'a ) Drupal Konsolu tarafından oluşturulabilir; dolayısıyla gerçekte yeni bir özel modül oluşturduğunuzda kendiniz kodlayın. Fakat öğrenme amaçları için önce bunu elden yapmaktan hoşlanırım.

Modülünüzü adlandırın

Drupal 7'de olduğu gibi, ilk iş modülün adını vermektir. Sistem boyunca kullanılacak bir makine adı oluşturmamız gerekiyor. Makine adları, modülünüzdeki işlev ve yöntemlerde kullanılır. Modülünüzün adlandırılması hakkında daha fazla bilgi için, [adlandırma ve Drupal 8 modülünüzün yerleştirilmesi] bölümünü drupal.org'da kontrol edin.

Bu modül First Modülünü first_module adlı bir makine adıyla arayacağım .

Modül klasörünü oluştur

Drupal 7'de, çekirdek modülleri / modules dizininde bulunur ve özel ve katkıda bulunan modüllerinizi, siteler / all / modules dizini veya siteler / sitename / modules dizinine yerleştirmelisiniz. D8'de çekirdek modülleri / core dizinine girersiniz, böylece contrib ve özel modüllerinizi / modules dizinine yerleştirebilirsiniz. Drupal 7 uygulamasıyla sadık kalacağım ve onları siteler / hepsi / modüller halinde koyacağım.

  • Tüm sitelerde / sitelerde yeni bir dizin oluştur
  • İçinde her şey bir dizin modülleri yaratır
  • Tüm dizinin içinde first_module adlı dizini oluşturun

Bir bilgi yaml dosyası oluştur

Drupal'a modülünüzün var olduğunu söylemek için bir info yaml dosyası oluşturmanız gerekir. Bu, Drupal 7'de bir .info dosyası oluşturmakla benzer.

Dosya adı, .info.yml uzantılı modülünüzün makine adı olmalıdır. Bu durumda, ilk_module.info.yml olacaktır.

  • First_module.info.yml dosyasını first_module dizininin kök dizininde oluşturun.
    name: First Module
    description: An experimental module to build our first Drupal 8 module
    package: Custom
    type: module
    version: 1.0
    core: 8.x

.yml dosyaları hakkında daha fazla bilgi .

.module dosyası oluştur

Drupal 7'de, herhangi bir kod içermese bile .module gereklidir. Drupal 8'de isteğe bağlıdır. Kancaları uygulamak istiyorsanız daha sonra kullanılabilecek bir tane oluşturacağım.

  • First_module dizininin kök dizininde first_module.module adlı bir tane oluşturun.

Src dizini oluştur

Denetleyiciler, eklentiler, formlar, şablonlar ve testler için modül dizini içinde bir alt dizin oluşturmamız gerekir. Bu alt dizin kaynağı olarak kısa olan src olarak adlandırılmalıdır. Bu, denetleyici sınıfının otomatik olarak yüklenmesine izin verecek ve bu da sınıf dosyasını açıkça eklemeniz gerekmediği anlamına geliyor.

  • Kaynak adı kısa olan src adlı first_module modül klasöründe bir klasör oluşturun.

Basit bir denetleyici oluştur

Denetleyiciler, işin çoğunu tipik bir MVC uygulamasında yapar. Modül için temel denetleyiciyi oluşturma adımları şunlardır:

  • Controller adlı src içinde bir klasör oluşturun.
  • Controller klasörü içinde FirstController.php adlı bir dosya oluşturun.

FirstController.php'de, çalıştığını bildiğimizden basit bir "merhaba dünya" mesajı oluşturacağız.

<?php
/**
 * @file
 * Contains \Drupal\first_module\Controller\FirstController.
 */
 
namespace Drupal\first_module\Controller;
 
use Drupal\Core\Controller\ControllerBase;
 
class FirstController extends ControllerBase {
  public function content() {
    return array(
      '#type' => 'markup',
      '#markup' => t('Hello world'),
    );
  }

Bir rota dosyası ekle

Yukarıda oluşturduğumuz kumanda birimi bu aşamada hiçbir şey yapmayacaktır. URL'nin yürütülebilmesi için onu URL'den denetleyiciye giden bir rotaya bağlamamız gerekir.

  • First_module.routing.yml adlı bir dosya oluşturun
  • Aşağıdaki kodu first_module.routing.yml'a ekleyin
    first_module.content:
      path: '/first'
      defaults:
        _controller: 'Drupal\first_module\Controller\FirstController::content'
        _title: 'Hello world'
      requirements:
        _permission: 'access content'

Içeriği izle

Henüz yapmadıysanız, modülü etkinleştirin.

Şimdi / ilk giderseniz, denetleyiciden geri gönderilen Merhaba Dünya iletisini görürsünüz.

Menü bağlantısı oluştur

Rota şimdi çalışır ve denetleyiciden içerik döndürür. Ancak, içeriğe erişebilmek için URL'yi bilmeniz gerekir. Bunu daha kullanışlı kılmak için, onu Drupal'ın menü sistemine eklememiz gerekiyor. Bunu yapmak için, bir menü .yml dosyası oluşturmanız gerekir.

  • Modül kök dizininde first_module.links.menu.yml oluşturun
  • Aşağıdakileri ekleyin:
    first_module.admin:
      title: 'First module settings'
      description: 'A basic module to return hello world'
      parent: system.admin_config_development
      route_name: first_module.content
      weight: 100
  • Önbelleği boşaltın ve ardından yapılandırma -> geliştirme altında menü öğesini görmeniz gerekir.
  • Menü maddesini tıkladığınızda ilk önce sizi götürecektir.

Ve işte bu, bir şey getiren bir menü öğesiyle ilk Drupal 8 modülünüz!

Özel bir blok

Şimdiye kadar, bir başlık ve dizeyi görüntüleyen bir özel yolumuz ve menü öğemiz var. Biraz daha heyecan verici bir şey yapalım ve modüle özel bir blok ekleyelim.

Öncelikle, modül için yeni bir eklenti yaratmamız gerekiyor. Eklentiler Drupal 8'de yenidir ve değiştirilebilir işlevsellik parçaları sağlar.

  • Başlamak için modülün Plugin adlı src klasöründe yeni bir dizin oluşturun. Burası bu modül için tüm eklentilerinizi depolayabileceğiniz yerdir.
  • Ardından Blok adlı bir klasör oluşturun. Blok, bir eklenti türüdür.
  • Block klasöründe, HelloBlock.php adlı bir dosya oluşturun.

Bu dosyada, ad alanını ve sınıfı tanımlamamız gerekir. PHPStorm gibi bir IDE kullanırsanız, bu otomatik olarak oluşturulacaktır.

    <?php
     
    namespace Drupal\first_module\Plugin\Block;
     
    class HelloBlock extends BlockBase {
     
    }

BlockCase sınıfını genişletmeniz gerekiyor. Bunu yapmak için, aşağıdaki use ifadesini ekleyin:

Drupal \ Core \ Block \ BlockBase kullanın;

Ve daha sonra HelloBlock sınıfını HelloBlock'a geçirirken BlockBase genişletir.

    <?php
     
    namespace Drupal\first_module\Plugin\Block;
    use Drupal\Core\Block\BlockBase;
     
    class HelloBlock extends BlockBase {
     
    }

Blok için kullanmamız gereken Drupal için bir başka yeni kavram, Ek açıklamalar. Drupal'ın blok kodunuzu bulması için, bir Açıklamayı çağıran belirli bir şekilde bir kod yorumlaması uygulamalısınız.

  • Aşağıdaki yorumu ekleyin : class HelloBlock, BlockBase'yi genişletir :
    /**
     * Provides a 'Hello' Block
     *
     * @Block(
     *   id = "hello_block",
     *   admin_label = @Translation("Hello block"),
     * )
     */

Ardından, dokümanları temel sınıftan devralmamız ve blok içeriğini döndürecek bir yapı yöntemi eklememiz gerekiyor.

    class HelloBlock extends BlockBase {
      /**
       * {@inheritdoc}
       */
      public function build() {
      return array(
          '#markup' => $this->t('Hello, World!'),
       );
      }
    }

HelloBlock.php'nin tam kodu

    <?php
    /**
     * @file
     * Contains \Drupal\first_module\Plugin\Block\HelloBlock.
     */
     
    namespace Drupal\first_module\Plugin\Block;
    use Drupal\Core\Block\BlockBase;
     
    /**
     * Provides a 'Hello' Block
     *
     * @Block(
     *   id = "hello_block",
     *   admin_label = @Translation("Hello block"),
     * )
     */
    class HelloBlock extends BlockBase {
      /**
       * {@inheritdoc}
       */
      public function build() {
        return array(
          '#markup' => $this->t('Hello, World!'),
        );
      }
     
    }

Blok Yeri

Sonra önbelleği temizlemeniz gerekir. Ve sonra bloğu bir bölgeye eklemek için, bloklar admin sayfasına gidin. Blok, yan çubuğun ilk bölgesine eklemek için Yerleştir bloğunu tıklayın.

Görsel kaldırıldı.

Mevcut blokların bir listesi ile bir model görüntülenir. Yeni oluşturduğunuz Merhaba bloğu bulmak için merhaba arayın. İşlemler sütunundaki Blok yerleştir düğmesini tıklayın.

Görsel kaldırıldı.

Daha sonra  bloğun yapılandırma formunu göreceksiniz.

kayıt edin.

Görsel kaldırıldı.

Ardından, bloklar düzen sayfasının en altına gidin ve blokları kaydet'i tıklayın. Şimdi bloğu sitenizin sol kenar çubuğunda görmelisiniz.

Görsel kaldırıldı.

Dosya yapısına genel bakış

Yukarıdaki adımları tamamladıktan sonra, aşağıdaki gibi bir dosya yapısına sahip olmalısınız:

Görsel kaldırıldı.

Özet

Bu öğreticide, temel bir Drupal 8 modülü oluşturdunuz, bir dize döndüren ve özel bir blok oluşturan bir denetleyiciye bir URL eşleştirdiniz. Kavramlar bu aşamada tamamen yabancıysa endişelenmeyin. Sadece pratik yapmaya devam edin ve zamanla her şey netleşecektir. Ve unutmayın, yalnız değilsiniz - Drupal 8'e geçiş, tüm Drupal topluluğunun başlattığı bir yolculuk. Drupal konusunda desteğe ihtiyaçınız olursa ilettişim kurmaktan çekinmeyin.

Mutlu kodlamalar :)

Wordpress'ten Drupal'e İçerik Taşıma Nasıl Yapılır?

Wordpress'ten Drupal'e İçerik Taşıma Nasıl Yapılır?

Wordpress oldukça populer bir içerik yönetim sistemidir. Daha çok blog ve haber sitelerinde kullanılmaktadır. Drupal kadar esnek bir yapısı yoktur. Her teknolojinin avantajları ve dez avantajları vardır. Ayrıca Wordpress zamanla web site sahiplerini proje büyükçe bir çok sıkıntıya sokabilmektedir.

Wordpress'de en çok soruna neden olan başlıca bulgular ise;

1) Hız ( Zamanda web sitesi çok fazla hantallaşmaktadır.)

2) CPU yu çok fazla yorması

3) Güvenlik (Daha çok sİte yönetimi ile alakalı olsada bu durum epey can sıkmaktadır.)

Bu nedenle Drupal, Wordpress'den sonra iyi bir tercih olacaktır. Blog yazısında size Wordpress'den Drupal 8'e içerik ve resimlerin nasıl aktarılğını anlatmaya çalışacağız.

İçerik aktarımı için Migrate drush modulunu kullanacağız.

Öncelikle, settings.php dosyanızda aktarmak istediğiniz veri tabanı bağlantı bilgilerinizi yapılandırdığınızdan emin olun. Uygun kimlik bilgilerini aşağıdaki örnekteki gibi ekleyin:

$databases['migrate']['default'] = [
    'driver'   => 'mysql',
    'database' => 'wordpress_dbname',
    'username' => 'wordpress_dbuser',
    'password' => 'wordpress_dbpassowrd',
    'host'     => '127.0.0.1',
];

İşte kullanacağımız modül yapısı:

wp_migration/
  - wp_migration.info.yml
  - wp_migration.module
  - migration_templates/
    - wp_content.yml
    - wp_thumbnail.yml
    - wp_media.yml
  - src/
    - Plugin/
      - migrate/
        - process/
          - AddUrlAliasPrefix.php
          - DateToTimestamp.php
        - source/
          - SqlBase.php
          - Content.php
          - Thumbnail.php

wp_wordpress.info.yml dosyasının içeriği:

name: Wordpress Migration
type: module
description: Migrate Wordpress content into Drupal 8.
core: 8.x
dependencies:
  - migrate
  - migrate_drupal
  - migrate_drush

migration_templates/wp_thumbnail.yml dosyasının içeriği:

id: wp_thumbnail
label: 'Thumbnails'
migration_tags:
  - Wordpress
source:
  plugin: wordpress_thumbnail
  # This is WP table prefix  (custom variable)
  # DB table example: [prefix]_posts
  table_prefix: wp
  constants:
    # This path should point ot WP uploads directory.
    source_base_path: '/path/to/source/wp/uploads'
    # This is directory name in Drupal where to store migrated files
    uri_file: 'public://wp-thumbnails'
process:
  filename: filename
  source_full_path:
    -
      plugin: concat
      delimiter: /
      source:
        - constants/source_base_path
        - filepath
    -
      plugin: urlencode
  uri_file:
    -
      plugin: concat
      delimiter: /
      source:
        - constants/uri_file
        - filename
    -
      plugin: urlencode
  uri:
    plugin: file_copy
    source:
      - '@source_full_path'
      - '@uri_file'
  status: 
    plugin: default_value
    default_value: 1
  changed: 
    plugin: date_to_timestamp
    source: post_date
  created: 
    plugin: date_to_timestamp
    source: post_date
  uid: 
    plugin: default_value
    default_value: 1
destination:
  plugin: 'entity:file'
migration_dependencies:
  required: {}
  optional: {}

migration_templates/wp_media.yml dosyasının içeriği:

id: wp_media
label: 'Media'
migration_tags:
  - Wordpress
source:
  plugin: wordpress_thumbnail
  # This is WP table prefix  (custom variable)
  # DB table example: [prefix]_posts
  table_prefix: wp
  constants:
    bundle: image
process:
  bundle: 'constants/bundle'
  langcode:
    plugin: default_value
    default_value: en
  'field_image/target_id':
    -
      plugin: migration
      migration: wp_thumbnail
      source: post_id
    -
      plugin: skip_on_empty
      method: row
destination:
  plugin: 'entity:media'
migration_dependencies:
  required: {}
  optional: {}

migration_templates/wp_content.yml dosyasının içeriği:

id: wp_content
label: 'Content'
migration_tags:
  - Wordpress
source:
  plugin: wordpress_content
  # Wordpress post type (custom variable)
  post_type: post
  # This is WP table prefix  (custom variable)
  # DB table example: [prefix]_posts
  table_prefix: wp
process:
  type:
    plugin: default_value
    default_value: article
  'path/pathauto':
    plugin: default_value
    default_value: 0
  'path/alias':
    # This will add the following to URL aliases in Drupal
    plugin: add_url_alias_prefix
    # url/alias/prefix/2017/07/21/[post-title]
    prefix: url/alias/prefix
    source: path_alias
  promote: 
    plugin: default_value
    default_value: 0
  sticky: 
    plugin: default_value
    default_value: 0
  langcode:
    plugin: default_value
    default_value: en
  status: 
    plugin: default_value
    default_value: 1
  title: post_title
  created: 
    plugin: date_to_timestamp
    source: post_date
  changed: 
    plugin: date_to_timestamp
    source: post_modified
  field_image:
    -
      plugin: migration
      migration: wp_media
      source: thumbnail
    -
      plugin: skip_on_empty
      method: row
  'body/summary': post_excerpt
  'body/format':
    plugin: default_value
    default_value: full_html
  'body/value': post_content
destination:
  plugin: 'entity:node'
migration_dependencies:
  required: {}
  optional: {}

src/Plugin/migrate/process/AddUrlAliasPrefix.php dosyasının içeriği;

<?php

namespace Drupal\wp_migration\Plugin\migrate\process;

use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Row;

/**
 * Add prefix to URL aliases.
 *
 * @MigrateProcessPlugin(
 *   id = "add_url_alias_prefix"
 * )
 */
class AddUrlAliasPrefix extends ProcessPluginBase {

  /**
   * {@inheritdoc}
   */
  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
    $prefix = !empty($this->configuration['prefix']) ? '/' . $this->configuration['prefix'] : '';
    return $prefix . $value;
  }

}

src/Plugin/migrate/process/DateToTimestamp.php dosyasının içeriği;

<?php

namespace Drupal\wp_migration\Plugin\migrate\process;

use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Row;

/**
 * Date to Timetamp conversion.
 *
 * @MigrateProcessPlugin(
 *   id = "date_to_timestamp"
 * )
 */
class DateToTimestamp extends ProcessPluginBase {

  /**
   * {@inheritdoc}
   */
  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
    return strtotime($value . ' UTC');
  }

}

src/Plugin/migrate/source/SqlBase.php dosyasının içeriği; 4

<?php

namespace Drupal\wp_migration\Plugin\migrate\source;

use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
use Drupal\migrate\Row;

class SqlBase extends DrupalSqlBase {

  /**
   * Get database table prefix from the migration template.
   */
  protected function getPrefix() {
    return !empty($this->configuration['table_prefix']) ? $this->configuration['table_prefix'] : 'wp';
  }

  /**
   * Get Wordpress post type from the migration template.
   */
  protected function getPostType() {
    return !empty($this->configuration['post_type']) ? $this->configuration['post_type'] : 'post';
  }

  /**
   * Generate path alias via pattern specified in `permalink_structure`.
   */
  protected function generatePathAlias(Row $row) {
    $prefix = $this->getPrefix();
    $permalink_structure = $this->select($prefix . '_options', 'o', ['target' => 'migrate'])
      ->fields('o', ['option_value'])
      ->condition('o.option_name', 'permalink_structure')
      ->execute()
      ->fetchField();
    $date = new \DateTime($row->getSourceProperty('post_date'));
    $parameters = [
      '%year%'     => $date->format('Y'),
      '%monthnum%' => $date->format('m'),
      '%day%'      => $date->format('d'),
      '%postname%' => $row->getSourceProperty('post_name'),
    ];
    $url = str_replace(array_keys($parameters), array_values($parameters), $permalink_structure);
    return rtrim($url, '/');
  }

  /**
   * Get post thumbnail.
   */
  protected function getPostThumbnail(Row $row) {
    $prefix = $this->getPrefix();
    $query = $this->select($prefix . '_postmeta', 'pm', ['target' => 'migrate']);
    $query->innerJoin($prefix . '_postmeta', 'pm2', 'pm2.post_id = pm.meta_value');
    $query->fields('pm', ['post_id'])
      ->condition('pm.post_id', $row->getSourceProperty('id'))
      ->condition('pm.meta_key', '_thumbnail_id')
      ->condition('pm2.meta_key', '_wp_attached_file');
    return $query->execute()->fetchField();
  }

}

src/Plugin/migrate/source/Thumbnail.php dosyasının içeriği;

<?php

namespace Drupal\wp_migration\Plugin\migrate\source;

use Drupal\migrate\Row;

/**
 * Extract content thumbnails.
 *
 * @MigrateSource(
 *   id = "wordpress_thumbnail"
 * )
 */
class Thumbnail extends SqlBase {

  /**
   * {@inheritdoc}
   */
  public function query() {
    $prefix = $this->getPrefix();
    $query = $this->select($prefix . '_postmeta', 'pm', ['target' => 'migrate']);
    $query->innerJoin($prefix . '_postmeta', 'pm2', 'pm2.post_id = pm.meta_value');
    $query->innerJoin($prefix . '_posts', 'p', 'p.id = pm.post_id');
    $query->fields('pm', ['post_id']);
    $query->fields('p', ['post_date']);
    $query->addField('pm2', 'post_id', 'file_id');
    $query->addField('pm2', 'meta_value', 'filepath');
    $query
      ->condition('pm.meta_key', '_thumbnail_id')
      ->condition('pm2.meta_key', '_wp_attached_file')
      ->condition('p.post_status', 'publish')
      ->condition('p.post_type', 'post');
    return $query;
  }

  /**
   * {@inheritdoc}
   */
  public function fields() {
    return [
      'post_id'   => $this->t('Post ID'),
      'post_date' => $this->t('Media Uploaded Date'),
      'file_id'   => $this->t('File ID'),
      'filepath'  => $this->t('File Path'),
      'filename'  => $this->t('File Name'),
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getIds() {
    return [
      'post_id' => [
        'type'  => 'integer',
        'alias' => 'pm2',
      ],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function prepareRow(Row $row) {
    $row->setSourceProperty('filename', basename($row->getSourceProperty('filepath')));
  }


src/Plugin/migrate/source/Content.php

<?php

namespace Drupal\wp_migration\Plugin\migrate\source;

use Drupal\migrate\Row;

/**
 * Extract content from Wordpress site.
 *
 * @MigrateSource(
 *   id = "wordpress_content"
 * )
 */
class Content extends SqlBase {

  /**
   * {@inheritdoc}
   */
  public function query() {
    $prefix = $this->getPrefix();
    $query = $this->select($prefix . '_posts', 'p');
    $query
      ->fields('p', [
        'id',
        'post_date',
        'post_title',
        'post_content',
        'post_excerpt',
        'post_modified',
        'post_name'
      ]);
    $query->condition('p.post_status', 'publish');
    $query->condition('p.post_type', $this->getPostType());
    return $query;
  }

  /**
   * {@inheritdoc}
   */
  public function fields() {
    return [
      'id'            => $this->t('Post ID'),
      'post_title'    => $this->t('Title'),
      'thumbnail'     => $this->t('Post Thumbnail'),
      'post_excerpt'  => $this->t('Excerpt'),
      'post_content'  => $this->t('Content'),
      'post_date'     => $this->t('Created Date'),
      'post_modified' => $this->t('Modified Date'),
      'path_alias'    => $this->t('URL Alias'),
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getIds() {
    return [
      'id' => [
        'type'  => 'integer',
        'alias' => 'p',
      ],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function prepareRow(Row $row) {
    // This will generate path alias using WP alias settings.
    $row->setSourceProperty('path_alias', $this->generatePathAlias($row));
    // Get thumbnail ID and pass it to the wp_media migration plugin.
    $row->setSourceProperty('thumbnail', $this->getPostThumbnail($row));
  }

}

ÖNEMLİ: Taşıma işlemlerini doğru sırayla gerçekleştirmelisiniz. Bu örnekte önce wp_thumbnail'ı, wp_media second ve wp_content'i en son çalıştırmalısınız.

Mutlu kodlamalar

Drupal 8'de Entity ile Otomatik Tamamlanan Sonuçları Nasıl Değiştirebilirim?

Drupal 8'de Entity ile Otomatik Tamamlanan Sonuçları Nasıl Değiştirebilirim?

Bazen, otomatik tamamlama sonuçlarında ek veriler görüntülemek, örneğin başlığın yanında içerik dili eklemek veya varlık türünü veya diğer ilgili verileri görüntülemek isteyebilirsiniz. Bu blog yazısında, Drupal 8'deki otomatik tamamlama alanlarındaki önerileri nasıl değiştireceğim göstereceğim.

İşte kullanacağımız modül yapısı:

alter_entity_autocomplete/
  - alter_entity_autocomplete.info.yml
  - alter_entity_autocomplete.services.yml
  - src/
    - EntityAutocompleteMatcher.php
    - Controller/
      - EntityAutocompleteController.php
    - Routing/
      - AutocompleteRouteSubscriber.php

alter_entity_autocomplete.info.yml dosyasının içeriği:

name: Alter Entity Autocomplete
description: The module alters entity autocomplete suggestion list.
type: module
core: 8.x

alter_entity_autocomplete.services.yml dosyasının içeriği:

services:

  alter_entity_autocomplete.route_subscriber:
    class: Drupal\alter_entity_autocomplete\Routing\AutocompleteRouteSubscriber
    tags:
      - { name: event_subscriber }

  alter_entity_autocomplete.autocomplete_matcher:
    class: Drupal\alter_entity_autocomplete\EntityAutocompleteMatcher
    arguments: ['@plugin.manager.entity_reference_selection']

src/EntityAutocompleteMatcher.php dosyasının içeriği. Sonuçların çıktısını değiştireceğiniz dosya budur: sugesstions/autocomplete

<?php

namespace Drupal\alter_entity_autocomplete;

use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\Tags;

class EntityAutocompleteMatcher extends \Drupal\Core\Entity\EntityAutocompleteMatcher {

  /**
   * Gets matched labels based on a given search string.
   */
  public function getMatches($target_type, $selection_handler, $selection_settings, $string = '') {

    $matches = [];

    $options = [
      'target_type'      => $target_type,
      'handler'          => $selection_handler,
      'handler_settings' => $selection_settings,
    ];

    $handler = $this->selectionManager->getInstance($options);

    if (isset($string)) {
      // Get an array of matching entities.
      $match_operator = !empty($selection_settings['match_operator']) ? $selection_settings['match_operator'] : 'CONTAINS';
      $entity_labels = $handler->getReferenceableEntities($string, $match_operator, 10);

      // Loop through the entities and convert them into autocomplete output.
      foreach ($entity_labels as $values) {
        foreach ($values as $entity_id => $label) {

          $entity = \Drupal::entityTypeManager()->getStorage($target_type)->load($entity_id);
          $entity = \Drupal::entityManager()->getTranslationFromContext($entity);

          $type = !empty($entity->type->entity) ? $entity->type->entity->label() : $entity->bundle();
          $status = '';
          if ($entity->getEntityType()->id() == 'node') {
            $status = ($entity->isPublished()) ? ", Published" : ", Unpublished";
          }

          $key = $label . ' (' . $entity_id . ')';
          // Strip things like starting/trailing white spaces, line breaks and tags.
          $key = preg_replace('/\s\s+/', ' ', str_replace("\n", '', trim(Html::decodeEntities(strip_tags($key)))));
          // Names containing commas or quotes must be wrapped in quotes.
          $key = Tags::encode($key);
          $label = $label . ' (' . $entity_id . ') [' . $type . $status . ']';
          $matches[] = ['value' => $key, 'label' => $label];
        }
      }
    }

    return $matches;
  }

}

src/Controller/EntityAutocompleteController.php dosyasının içeriği:

<?php

namespace Drupal\alter_entity_autocomplete\Controller;

use Drupal\Core\KeyValueStore\KeyValueStoreInterface;
use Drupal\alter_entity_autocomplete\EntityAutocompleteMatcher;
use Symfony\Component\DependencyInjection\ContainerInterface;

class EntityAutocompleteController extends \Drupal\system\Controller\EntityAutocompleteController {

  /**
   * The autocomplete matcher for entity references.
   */
  protected $matcher;

  /**
   * {@inheritdoc}
   */
  public function __construct(EntityAutocompleteMatcher $matcher, KeyValueStoreInterface $key_value) {
    $this->matcher = $matcher;
    $this->keyValue = $key_value;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('alter_entity_autocomplete.autocomplete_matcher'),
      $container->get('keyvalue')->get('entity_autocomplete')
    );
  }

}

src/Routing/AutocompleteRouteSubscriber.php dosyasının içeriği:

<?php

namespace Drupal\alter_entity_autocomplete\Routing;

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;

class AutocompleteRouteSubscriber extends RouteSubscriberBase {

  public function alterRoutes(RouteCollection $collection) {
    if ($route = $collection->get('system.entity_autocomplete')) {
      $route->setDefault('_controller', '\Drupal\alter_entity_autocomplete\Controller\EntityAutocompleteController::handleAutocomplete');
    }
  }

}

Mutlu kodlamalar

Linux’ta Spectre & Meltdown CPU Kontrolü Nasıl Yapılır?

Meltdown ve Spectre

Meltdown ve Spectre Nedir?

Meltdown ve Spectre, modern işlemcilerde bulunan ve şimdiye kadar keşfedilen en ciddi güvenlik açıkları arasında yer alan iki kritik güvenlik açığıdır. Bu açıklar, tüm işletim sistemlerini (Windows, MacOS, Linux) ve bu işletim sistemleri üzerinde çalışan cihazları etkileyebilmektedir.

Bu güvenlik açıkları, işlemcilerin tasarımındaki bazı özelliklerden yararlanarak programların, normalde erişim izni olmayan verileri okumasına olanak tanır. Meltdown ve Spectre, kötü niyetli bir programın diğer programların belleğinde saklanan hassas verilere erişmesine izin verir. Bu veriler arasında şifre yöneticilerinde veya web tarayıcılarında saklanan parolalar, kişisel fotoğraflar, e-postalar, anlık iletiler ve iş için kritik olan belgeler bulunabilir.

Meltdown ve Spectre, kişisel bilgisayarlarda, mobil cihazlarda ve bulut hizmetlerinde çalışabilir. Bulut sağlayıcısının altyapısına bağlı olarak, bir kullanıcının diğer müşterilere ait verilere erişmesi mümkün olabilir.

Ubuntu Kullanıcıları İçin Güncellemeler

Ubuntu kullanıcıları için kernel güncellemeleri 9 Ocak'ta yayınlandı. Güncellenen çekirdek sürümleri şu şekildedir:

  • Ubuntu 20.04 LTS (Focal) — Linux 5.4
  • Ubuntu 18.04 LTS (Bionic) — Linux 4.15
  • Ubuntu 16.04 LTS (Xenial) — Linux 4.4
  • Ubuntu 14.04 LTS (Trusty) — Linux 3.13
  • Ubuntu 12.04 ESM (Precise) — Linux 3.2

Sisteminizin Meltdown ve Spectre güvenlik açıklarından etkilenip etkilenmediğini kontrol etmek için Spectre & Meltdown Checker isimli scripti kullanabilirsiniz. Bu scripti kurmak için aşağıdaki adımları takip edin:

cd /tmp/
wget https://raw.githubusercontent.com/speed47/spectre-meltdown-checker/master/spectre-meltdown-checker.sh
sudo sh spectre-meltdown-checker.sh

Linux kullanıcıları için güvenlik güncellemeleri gelmeye devam etmektedir. Sisteminizi düzenli olarak güncelleyerek bu tür güvenlik açıklarından korunmaya çalışın.

Servisleri Çalıştırma ve Durdurma

Apache için:

  • Çalıştırmak için: sudo systemctl start apache2
  • Durdurmak için: sudo systemctl stop apache2
  • Yeniden başlatmak için: sudo systemctl restart apache2

MySQL için:

  • Çalıştırmak için: sudo systemctl start mysql
  • Durdurmak için: sudo systemctl stop mysql
  • Yeniden başlatmak için: sudo systemctl restart mysql

Nginx'te Statik Dosyaları Önbellekte Saklama

Nginx'te Statik Dosyaları Önbellekte Saklama

Nginx'te statik dosyaları önbellekte nasıl saklayabilirim?

Bu ders, nginx'i, statik dosyaların (resim, CSS ve Javascript dosyaları gibi) Expires HTTP üstbilgisini ve Cache-Control HTTP üstbilgisinin maksimum yaş yönergesini gelecekte bir tarihe ayarlayacak şekilde nasıl yapılandırabileceğinizi açıklar; böylece bu dosyaların Ziyaretçilerinizin tarayıcıları tarafından önbelleğe alınacaktır. Bu, bant genişliğini azaltır ve web sitenizi daha hızlı görünmesini sağlar (bir kullanıcı sitenizi ikinci kez ziyaret ederse, statik dosyalar tarayıcı önbelleğinden getirilir). Çalışan bir nginx kurulumunuz olduğunu varsayıyorum, ör. Bu öğreticide gösterildiği gibi: Ubuntu'da LEMP (Nginx, MySQL, PHP) Server ve phpMyAdmin Kurulumu
Web sitenizin vhost dosyasına aşağıdaki satırları ekleyin.

location ~*  .(jpg|jpeg|png|gif|ico|css|js)$ {
expires 365d;
}

Yukarıdaki örnekte, tüm .jpg, .jpeg, .png, .gif, .ico, .css ve .js dosyaları gelecekte tarayıcı erişim süresinden 365 gün sonra bir tarih içeren bir Expires başlığı alıyor. Bu nedenle, {} bloğunun gerçekten yalnızca tarayıcılar tarafından önbelleğe alınabilen statik dosyaları içerdiğinden emin olmanız gerekir.

Değişikliklerinizden sonra nginx'u tekrar yükleyin:
/etc/init.d/nginx reload
Geçerlilik süresi aşağıdaki zaman ayarları yönergelerini kullanabilirsiniz.
Aşağıdaki zaman birimlerini kullarak önbellekleme süresini belirliyebilirsiniz.
Ms: milisaniye: s: saniyem: m: dakika: h: saat: d: gün: w: hafta M: ay (30 gün) y: yıl (365 gün) Örnek kullanım: 1 saat 30 dakika için 1h30m , bir yıl ve altı ay için 1y6M
nginx HttpHeadersModule: http://wiki.nginx.org/HttpHeadersModule ilgili kaynağı inceleyebilirsiniz.
Mutlu kodlamalar

Drupal'de Drupal Commerce için Özel Bir Ödeme Bölmesi Oluşturma

drupal commerce

Bu makalede, Drupal 10'da Drupal Commerce için nasıl özel bir ödeme bölmesi oluşturabileceğimizi göstereceğim. Bu amaçla yapılandırma formuna sahip bir ödeme bölmesi ve kullanıcıların siparişlerine kupon ekleme olanağı yaratacağız.

Drupal Commerce Özel Ödeme Bölmesi Oluşturma

namespace Drupal\module_name\Plugin\Commerce\CheckoutPane;

use Drupal\commerce_checkout\Plugin\Commerce\CheckoutFlow\CheckoutFlowInterface;
use Drupal\commerce_checkout\Plugin\Commerce\CheckoutPane\CheckoutPaneBase;
use Drupal\commerce_checkout\Plugin\Commerce\CheckoutPane\CheckoutPaneInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;

/**
 * Provides the coupons pane.
 *
 * @CommerceCheckoutPane(
 *   id = "coupons",
 *   label = @Translation("Redeem Coupon"),
 *   default_step = "order_information",
 * )
 */
class CommerceCoupons extends CheckoutPaneBase implements CheckoutPaneInterface {

/**
 * {@inheritdoc}
 */
public function __construct(array $configuration, $plugin_id, $plugin_definition, CheckoutFlowInterface $checkout_flow, EntityTypeManagerInterface $entity_type_manager) {
  parent::__construct($configuration, $plugin_id, $plugin_definition, $checkout_flow, $entity_type_manager);
}

Bu, özel ödeme bölmesinin bir 'kimlik kuponu' sahibi olacağı ve Ödül kuponu olarak etiketleneceği ve varsayılan olarak sipariş bilgi adımında belirleneceği anlamına gelir. Önce bölmemizin ayarlarını (yapılandırma) formunu oluşturuyoruz. Bu amaçla, kullanıcının sipariş üzerine yalnızca bir kupon kullanabileceği şekilde ayarlamamızı yapacağız. Bunun için, dört fonksiyon uygulamalıyız. Önce, varsayılan yapılandırmamızı kuracağız.

/**
 * {@inheritdoc}
 */
public function defaultConfiguration() {
  return [
      'single_coupon' => FALSE,
    ] + parent::defaultConfiguration();
}

Ardından yapılandırma formumuzun özetini uygulayacağız.

/**
 * {@inheritdoc}
 */
public function buildConfigurationSummary() {
  $summary = !empty($this->configuration['single_coupon']) ? $this->t('Single Coupon Usage on Order: Yes') : $this->t('Single Coupon Usage on Order: No');
  return $summary;
}

Sonra yapılandırma formumuzu oluşturacağız.

/**
 * {@inheritdoc}
 */
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
  $form = parent::buildConfigurationForm($form, $form_state);
  $form['single_coupon'] = [
    '#type' => 'checkbox',
    '#title' => $this->t('Single Coupon Usage on Order?'),
    '#description' => $this->t('User can enter only one coupon on order.'),
    '#default_value' => $this->configuration['single_coupon'],
  ];

  return $form;
}

Sonrasında bu ayarları kaydedin.

/**
 * {@inheritdoc}
 */
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
  parent::submitConfigurationForm($form, $form_state);

  if (!$form_state->getErrors()) {
    $values = $form_state->getValue($form['#parents']);
    $this->configuration['single_coupon'] = !empty($values['single_coupon']);
  }
}

Ödeme akışının düzenleme sayfasında nasıl görüneceğini görebilirsiniz. Sonra, bölme formumuzu oluşturacağız. Yapılandırmamızı kontrol edeceğiz ve siparişte bir kupon uygulanmışsa ve tek kupon için yapılandırma ayarına sahipse form göstermeyeceğiz.

/**
 * {@inheritdoc}
 */
public function buildPaneForm(array $pane_form, FormStateInterface $form_state, array &$complete_form) {
  $order_has_coupons = $this->order->coupons->referencedEntities();
  if($this->configuration['single_coupon'] && $order_has_coupons){
    return $pane_form;
  }
  $pane_form['coupon'] = [
    '#type' => 'textfield',
    '#title' => $this->t('Coupon'),
    '#default_value' => '',
    '#required' => FALSE,
  ];
  return $pane_form;
}

Bundan sonra, kuponlarımızın geçerliliğini uygulayacağız ve geçerli bir kuponun sağlanıp sağlanmadığını ve bu siparişe uygulanabilir olup olmadığını kontrol edeceğiz.

/**
 * {@inheritdoc}
 */
public function validatePaneForm(array &$pane_form, FormStateInterface $form_state, array &$complete_form) {
  $values = $form_state->getValue($pane_form['#parents']);
  if(!empty($values['coupon'])){
    $coupon_code = $values['coupon'];
    /* @var \Drupal\commerce_promotion\Entity\Coupon $commerce_coupon */
    $commerce_coupon = $this->entityTypeManager->getStorage('commerce_promotion_coupon')->loadByCode($coupon_code);
    $valid = false;
    if($commerce_coupon){
      $promotion = $commerce_coupon->getPromotion();
      $valid = $promotion->applies($this->order) ? true : false;
      if($valid){
        foreach($this->order->coupons->referencedEntities() as $coupon){
          if($commerce_coupon->id() == $coupon->id()){
            $form_state->setError($pane_form, $this->t('Coupon already applied to order.'));
          }
        }
      }
    }
    if(!$valid){
      $form_state->setError($pane_form, $this->t('The specified coupon does not apply for this order.'));
    }
  }
}

Bizim için bırakılan şey sipariş üzerine kuponu kaydetmek ve kupon işlemi yapmaktır. Bunun için, commerce_promotion_coupon işlemcisini kullanacağız.

/**
 * {@inheritdoc}
 */
public function submitPaneForm(array &$pane_form, FormStateInterface $form_state, array &$complete_form) {
  $values = $form_state->getValue($pane_form['#parents']);
  if(!empty($values['coupon'])){
    $coupon_code = $values['coupon'];
    $commerce_coupon = $this->entityTypeManager->getStorage('commerce_promotion_coupon')->loadByCode($coupon_code);
    if($commerce_coupon){
      $this->order->coupons[] = $commerce_coupon->id();
      $coupon_order_processor = \Drupal::service('commerce_promotion.promotion_order_processor');
      $coupon_order_processor->process($this->order);
      $this->order->save();
    }
  }
}

Bitirdik ve yeni ödeme bölmesini test edebiliriz. Mutlu kodlamalar!

Nginx nedir? Temel Özellikleri ve Nerede Kullanılır?

Nginx nedir? Temel Özellikleri ve Nerede Kullanılır?

Nginx nedir?

Nginx rus yazılım mühendisi Igor Sysoev tarafından geliştirilen hafif, stabil, hızlı bir mail istemcisi olarak kodlanan daha sonraları geliştirilerek tüm sunucular için uygun hale getirilen bir web sunucusudur.

Nginx özellikle yüksek trafikli ve yoğun istek girişi olan web siteleri için biçilmiş kaftandır. Single Thread yanıt yapısıyla sayfayı tek seferde indirip sayfa açılma hızında farkedilir büyük bir artış sağlar. Ayrıca nginx apache ve litespeed ile karşılaştırıldığında çok daha az cpu kullanır. Bu sebeple Nginx vps sunucular için biçilmiş kaftandır.

İnsanların Nginx i tercih etmemesinin en büyük sebebi destek sıkıntısı ve kurulum zorluğudur ancak nginx e hakim olan bir insan için yapılamayacak pek az şey vardır. Nginx kurulumunu bu yazımızda anlatmıştık.

Aşağıda özetleyeceğimiz üzerine web dosyalarınızı barındırabileceğiniz stabil çalışan ve güvenilir bir web sunucusudur.

Temel HTTP Özellikleri

* Statik ve index dosyalarının sunumu, otomatik indeksleme; açık dosya açıklayıcı önbellek;
* Önbellek ile hızlandırılmış reverse proxying; basit yük dengeleme ve hata toleransı;
* Uzak FastCgi sunucularının önbelleklenmesi ile hızlandırılmış destek; basit yük dengeleme ve hata toleransı;
* Modüler yapı. Gzip, byte aralıkları, yığın cevaplar (chunked responses), XSLT, SSI, imaj boyutlandırma gibi filtreler.
* SSL ve TLS SNI desteği.

Diğer HTTP Özellikleri

* Ad ve IP tabanlı sanal sunucular;
* Keep-alive ve pipelined bağlantı desteği;
* Esnek yapılandırma;
* İstemci işlemlerinde kopma olmadan yeniden yapılandırma ve online güncelleme;
* Erişim kayıt (log) formatları, tamponlanmış kayıt yazımı ve hızlı kayıt devri;
* 3xx-5xx hata kod yönlendirmeleri;
* rewrite modülü;
* İstemcinin IP adresine dayalı erişim kontrolü ve HTTP temel kimlik denetleme;
* PUT, DELETE, MKCOL, COPY ve MOVE methodları;
* FLV streaming;
* Hız sınırlandırma;
* Bir adresten gelen eşzamanlı bağlantı ve talepleri sınırlandırma.
* Gömülü perl.

Mail Proxy Sunucu Özellikleri

* Harici bir HTTP kimlik denetleme sunucusunu kullanarak, kullanıcıyı IMAP/POP3 backend’ine yönlendirme;
* Harici bir HTTP kimlik denetleme sunucusunu kullanarak, kullanıcıyı SMTP backend’ine yönlendirme ve kullanıcı kimlik denetlemesi;
* SSL desteği.
* STARTTLS ve STLS desteği.

Test Edilen İşletim Sistemleri ve Platformlar

* FreeBSD 3 — 8 / i386; FreeBSD 5 — 8 / amd64;
* Linux 2.2 — 2.6 / i386; Linux 2.6 / amd64;
* Solaris 9 / i386, sun4u; Solaris 10 / i386, amd64, sun4v;
* MacOS X / ppc, i386;
* Windows XP, Windows Server 2003

Nginx kurulumları ve gerekli ayarlarınız için bizimle iletişim kurabilirsiniz.

Mutlu kodlamalar

Linux Sistem Üzerinde Donanım Özelliklerini Ögrenme (Ubuntu, Debian, Fedora, CentOS vb.)

Linux Sistem Üzerinde Donanım Özelliklerini Ögrenme

Linux donanım bilgilerini nasıl ögrenebilirim?

Linux sisteminizin donanım özelliklerini merak ediyor yada ögrenmek istiyorsanız. Terminal üzerinde aşağıdaki yazacagımız birkaç komut satırı ile detaylı olarak ögrenebilirsiniz.

Aşağıdaki komutu terminal üzerinden çalıştırarak donanım listesine ulaşabilirsiniz.

sudo lshw -short

Daha detaylı çıkt için;

sudo lshw

Ya da ayrı ayrı ögrenmek için aşağıdaki yönergeleri takip edebilirsiniz.

Disk (Hard disk) Bilgileri

df -lh

Filesystem      Size  Used Avail Use% Mounted on
udev            3,9G  4,0K  3,9G    1% /dev
tmpfs           790M  1,3M  789M    1% /run
/dev/sda1       909G  4,4G  859G    1% /
none            4,0K     0  4,0K    0% /sys/fs/cgroup
none            5,0M     0  5,0M    0% /run/lock
none            3,9G  1,2M  3,9G    1% /run/shm
none            100M   60K  100M    1% /run/use

Disk bölümlendirmede kullanılan fdisk komudunu " -l " parametresini ekleyerek disklerin bölümlerini listelemek için kullanabiliriz. Bunun için root hesabı veya root yetkisi (sudo grubuna üye) bir kullanıcı gerekiyor.

sudo fdisk -l

Disk /dev/sda: 1000.2 GB, 1000204886016 bytes
255 heads, 63 sectors/track, 121601 cylinders, total 1953525168 sector
Units = sektör of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disk kimlikleyicisi: 0x000aa4bb

Device    Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048  1936928767   968463360   83  Linux
/dev/sda2      1936930814  1953523711     8296449    5  Ek
Partition 2 does not start on physical sector boundary.
/dev/sda5      1936930816  1953523711     8296448   82  Linux takas / Solaris
...

İşlemci (CPU) Bilgileri

İşlemci hakkında deyatlı olarak tüm bilgileri ögrenebilirsiniz.

cat /proc/cpuinfo

processor	: 0
vendor_id	: GenuineIntel
cpu family	: 6
model		: 60
model name	: Intel(R) Core(TM) i7-4700MQ CPU @ 2.40GHz
stepping	: 3
microcode	: 0x16
cpu MHz		: 2597.250
cache size	: 6144 KB
physical id	: 0
siblings	: 8
core id		: 0
cpu cores	: 4
apicid		: 0
initial apicid	: 0
fpu		: yes
fpu_exception	: yes
cpuid level	: 13
wp		: yes
...

Sisteminizdeki işlemcinizin kaçtane fiziksel çekirdiği var? Ögrenmek istiyorsanız. Yukardaki yazdığımız komut satırının sonuna " | grep cores " ekleyerek ögrenebiliriz.

cat /proc/cpuinfo | grep cores

cpu cores	: 4
cpu cores	: 4
cpu cores	: 4
cpu cores	: 4
cpu cores	: 4
cpu cores	: 4
cpu cores	: 4
cpu cores	: 4

Komutu işleme koydugunuzda çıkan sonuç fiziksel çekirdek sayısını vermekle beraber aynı sonuçun kaç adet oluşturulduğuda sanal çekirdek sayısını göstermektedir. Yukarıdaki sonuç; "4" fiziksel çekirdek ve "8" sanal çekirdeğe (thread) sahip bir sistem olduğunu gösteriyor.

Bellek (RAM&Swap) Bilgileri

Sistemin ne kadar bellek miktarına sahip olduğunu ögrenmek istiyorsanız. Aşağıdaki komudu komut satırına yazarak ögrenebilirsiniz.

free -m


                                     total      used         free         shared   buffers     cached.
mem:                            7895       4020       3875        429         62         1669
-/+ buffers/cache:         2288       5607
swap:                            8101          0          8101

Total altında sistemin toplam belleği gözükmekte. -m parametresi sonucu megabyte formatında basmaktadır. Örnek çıktıda 8GB fiziksel bellek 2GB swap alanı gözükmektedir.

Grafik Kartı (GPU) Bilgileri

Sistem üzerinde çalışan grafik kartı bilgilerini öğrenmek için tüm PCI cihazlarını listeleyen lspci komudu kullanılabilir.

lspci | grep VGA

00:02.0 VGA compatible controller: Intel Corporation 4th Gen Core Processor Integrated Graphics Controller (rev 06)

Diğer Bilgiler (Ethernet, kablosuz, ses kartları vb.)

Sistem üzerinde çalışan diğer donanımları görmek için "lspci" komudu kullanılabilir.

lspci

00:00.0 Host bridge: Intel Corporation Xeon E3-1200 v3/4th Gen Core Processor DRAM Controller (rev 06)
00:01.0 PCI bridge: Intel Corporation Xeon E3-1200 v3/4th Gen Core Processor PCI Express x16 Controller (rev 06)
00:02.0 VGA compatible controller: Intel Corporation 4th Gen Core Processor Integrated Graphics Controller (rev 06)
00:03.0 Audio device: Intel Corporation Xeon E3-1200 v3/4th Gen Core Processor HD Audio Controller (rev 06)
00:14.0 USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB xHCI (rev 04)
00:16.0 Communication controller: Intel Corporation 8 Series/C220 Series Chipset Family MEI Controller #1 (rev 04)
00:1a.0 USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB EHCI #2 (rev 04)
00:1b.0 Audio device: Intel Corporation 8 Series/C220 Series Chipset High Definition Audio Controller (rev 04)
00:1c.0 PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express Root Port #1 (rev d4)
00:1c.2 PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express Root Port #3 (rev d4)
00:1c.3 PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express Root Port #4 (rev d4)
00:1d.0 USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB EHCI #1 (rev 04)
00:1f.0 ISA bridge: Intel Corporation HM86 Express LPC Controller (rev 04)
00:1f.2 SATA controller: Intel Corporation 8 Series/C220 Series Chipset Family 6-port SATA Controller 1 [AHCI mode] (rev 04)
00:1f.3 SMBus: Intel Corporation 8 Series/C220 Series Chipset Family SMBus Controller (rev 04)
01:00.0 3D controller: NVIDIA Corporation GK107M [GeForce GT 745M] (rev a1)
03:00.0 Network controller: Intel Corporation Wireless 7260 (rev 73)
04:00.0 Ethernet controller: Qualcomm Atheros QCA8171 Gigabit Ethernet (rev 10)

Soru görüş yada önerileriniz için bizimle iletişim kurmaktan çekinmeyiniz.

mutlu kodlamalar

Drupal ile Çoklu Dil Kullanımı

Drupal multi dil ekleme

Drupal web siteleri için çoklu dil kurulumu

Drupal ile hazırlanan bir web sitesini çok dilli bir yapı haline getirmek için; ilk yapılması gereken çekirdekte gelen "Locale" ve "Content translation" modullerini aktif etmek olucaktır. Modulleri aktif ettikten sonra "admin/config/regional/language/add" sayfasına giderek çevirini yapmak istediğiniz yeni bir dil eklemeniz gerekiyor.
Daha sonra hangi içerik tipinizin çok dilli olarak çevirmek istiyorsanız. İçerik türleri sayfasına giderek "/admin/structure/types/manage/" çevirilerini yapmak istediğiniz içerik türünü seçerek ayar sayfasındaki "Çoklu dil desteği" seçeneğini aktif etmeniz gerekiyor.

Buraya kadar her şey tamam ise!

Bu işlemlemleri yaptıktan sonra çoklu dil seçeneğini aktif hale getirdiğiniz içerik tipinizden yazacağınız her yazı için dil şeçmeniz için dil seçenekleri görüceksiniz.
Ek bir modul kurarak sistemi ve önceden kurduğunuz veya kuracağınız modullerin dil dosyalarını sistem tarafından otomatik indirilmesini isterseniz.
Localization update modulunu sisteminize kurabilirsiniz.

Ayrıca projede dil çevirilerinde ve filtrelerinde daha fazla opsiyon isterseniz Internationalization modulunu kurabilirsiniz.

Oluşturmak istediğiniz yapı çok kullanıcılı, intranet, portal, sosyal ağ tarzında bir proje işe daha profesyonel yardım almak için bizimle iletişime geçmekten çekinmeyiniz.

Mutlu kodlamalar.

Drush ile Tek Dosyada Kendi Dağıtımınızı Yapın

drupal drush

Drush generate-makefile ile Kendi Dağıtımınızı Yapın

Merhaba arkadaşlar, bugün size drush ın süpersonik bir işlevinden bahsedeceğim. Drupal kullananlar bilirler ki her kurulumda kullandığınız eklentileri ya site içerisinden tek tek eklemek gerekir ya da eklentileri tek tek indirip hepsini ftp den göndermeniz gerekmektedir. Drush kullanıyorsanız daha önce bu yazımda da bahsettiğim gibi drush dl projeismi şeklinde indirebiliyorsunuz.

Bu işlemleri daha pratik bir hale getirmek ve tek bir komut ile kendi eklenti, kütüphane, tema ve drupal çekirdeğinizi oluşturmak istiyorsanız son kez normal bir drupal kurulumu gerçekleştirerek olmazsa olmaz eklentiler, temalar, kütüphaneleri kurun. Terminalden drupal kurulumunuzun olduğu klasöre gidin.

Kendi dağıtımımızı oluşturmak için yapmamız gereken bir adım kaldı. O da aşağıdaki komutu çalıştırmak.

drush generate-makefile dosyaismi.make

Bu komutun drupal kurulumunu yaptığımız dizinde dosyaismi.make adında bir dosya oluşturduk. Tabi bu komut ile sitede kurulu olan modüllerin, temaların, kütüphanelerin ve drupal çekirdeğinin versiyonları ile birlikte kayıt etmiş olduk.

Görsel kaldırıldı.

Eğer versiyonları dahil etmeden bir dosya oluşturmak istiyorsak aşağıdaki gibi bir komut kullanmalıyız.

drush generate-makefile dosyaismi.make --exclude-versions

Bu komutun oluşturduğu dosyanın içeriği ise aşağıdaki gibi.

Görsel kaldırıldı.

Drush make ile oluşturduğunuz dosyadan pratik şekilde drupal kurmak

Drupal'ı kurmak istediğiniz klasör içerisinde aşağıdaki komutu çalıştırarak .make dosyasındaki drupal çekirdeği, modüller, temalar ve kütüphaneleri tek komut ile dizine indireceğiz.

drush make dosyaismi.make

Bu komut sonucunda kendi oluşturduğumuz .make dosyasında belirlediğimiz eklenti, tema, kütüphane ve drupal çekirdeğini tek komut ile indirmiş oluyoruz.

Belirli dosyaların ya da çekirdeğin versiyonsuz .make dosyasını oluşturmak için aşağıdaki komutu kullanıyoruz.

drush generate-makefile dosyaismi.make --exclude-versions=drupal,views,ctools

Veyahut tam tersi yani belirli projelerin versiyonlarını dahil etmek için aşağıdaki komutu kullanıyoruz.

drush generate-makefile dosyaismi.make --include-versions=admin_menu,panels,token

Görsel kaldırıldı.

Hepsi bu kadar...

Abone ol Nasıl Yapılır