LoginSignup
14
12

More than 5 years have passed since last update.

アンダースコアを含むテーブル名をFuelPHPのfromdbタスクでmodelを生成した時にディレクトリーが作成されてしまうのが嫌な場合

Last updated at Posted at 2014-05-24

記事を書くきっかけ

表題の通りで、例えばfizz_buzz_fizzbuzzという名前のテーブルのmodelをfromdbで生成すると、fuel/app/classes/model/fizz/buzz/fizzbuzz.phpというファイルが生成され、クラス名はModel_Fizz_Buzz_Fizzbuzzとなる。

これを、fuel/app/classes/model/fizzbuzzfizzbuzz.phpというファイルが生成され、クラス名はModel_Fizzbuzzfizzbuzzとなるようにしたかった。

対応にあたって

同じ事で悩んだ方で、生成されたファイルをmvしてrmしてbootstrap.phpAutoloader::add_classesする解決策があったが、fromdbの便利さを享受したかったため、この方法は見送った。FuelPHPなので、ファイル名にアンダースコアを使用したくなかった、というのも見送った事の遠因ではある。

fromdbが利用しているpackages/oil/classes/generate.phpmodelの処理で、ファイル名を決定する際に、アンダースコアとハイフンをdirectory separatorに置換するため、前述のような状態となる。

generate.phpfromdb.phpも修正したくなかったので、fromdbを元にしたfromdbunderscoreを作成した。

コード

使用方法は基本的にfromdbと同じです(ヘルプ変更していません...)

  1. --singularを指定しないと動作しないようにした。
  2. --crudが指定された場合動作しないようにした。
  3. -us-model-dir'でfuel/app/classes/model`の下にディレクトリーを指定出来るようにした。
  4. -us-base-modelで基底クラスを指定出来るようにした。
  5. 動作未検証なので-no-migrationを必ず指定する事。
fuel/app/tasks/fromdbunderscore.php
<?php

namespace Fuel\Tasks;

require_once(PKGPATH . 'oil/tasks/fromdb.php');

class Fromdbunderscore extends Fromdb
{
  const ORIGINAL_PARENT_CLASS_NAME  = '\Orm\Model';

  private static $_model_dir = '';
  private static $_parent_class_name = '';

  public static function crud($tables = '')
  {
    \Cli::write('fromdbunderscore does not support crud.', 'red');
    exit();
  }

  public static function model($tables = '')
  {
    // do we have any tables defined?
    if (empty($tables))
    {
      // do we want to generate for all tables?
      if ( ! \Cli::option('all', false))
      {
        \Cli::write('No table names specified to generate a model on.', 'red');
        exit();
      }

      // get the list of all available tables
      try
      {
        $list = \DB::list_tables(null, \Cli::option('db', null));
      }
      catch (\FuelException $e)
      {
        \Cli::write('The database driver configured does not support listing tables. Please specify them manually.', 'red');
        exit();
      }

      $prefix = \DB::table_prefix();
      $migration = \Config::get('migrations.table', 'migration');

      $tables = array();

      // create the table list
      foreach ($list as $table)
      {
        // strip any defined table prefix from the table name
        if ( ! empty($prefix) and strpos($table, $prefix) === 0)
        {
          $table = substr($table, strlen($prefix));
        }

        // skip the migration table
        $table == $migration or $tables[] = $table;
      }
    }

    // make sure we have an array to work with
    is_array($tables) or $tables = explode(',', $tables);

    static::_preprocess_for_generate();

    // generate for each table defined
    foreach ($tables as $table)
    {
      static::generate_model_under_score($table);
    }
  }

  protected static function _preprocess_for_generate()
  {
    if(empty(\Cli::option('singular', ''))){
      \Cli::write('You must specify the -singular option.', 'red');
      exit();
    }

    static::$_model_dir = \Cli::option('us-model-dir', '');

    static::$_parent_class_name = empty(\Cli::option('us-base-model', '')) ?
      static::ORIGINAL_PARENT_CLASS_NAME : \Cli::option('us-base-model');
  }

  protected static function generate_model_under_score($table)
  {
    // start with an empty list
    \Oil\Generate::$create_files = array();

    $args = static::arguments($table);

    // underscores are erased from table name
    $table_name_which_has_not_underscores = str_replace('_', '', $args[0]);
    $args[0] = $table_name_which_has_not_underscores;

    // and generate, but doesn't create a file.
    call_user_func('Oil\Generate::model', $args, false);

    $filename = \Oil\Generate::$create_files[0]['path'];

    // restore a table name in generated content
    $search = array(sprintf('$_table_name = \'%s\'', $table_name_which_has_not_underscores));
    $replace = array(sprintf('$_table_name = \'%s\'', $table));

    // normalize a class name in generated content
    $search[] = sprintf('Model_%s', ucfirst($table_name_which_has_not_underscores));
    $replace[] = sprintf('Model_%s', ucfirst(\Inflector::camelize($table)));

    // replace parent class name if neededed
    if(!empty(static::$_parent_class_name)){
      $search[] = static::ORIGINAL_PARENT_CLASS_NAME;
      $replace[] = static::$_parent_class_name;
    }

    $contents = str_replace($search, $replace, \Oil\Generate::$create_files[0]['contents']);

    $type = \Oil\Generate::$create_files[0]['type'];

    $model_dir = empty(static::$_model_dir) ?
      dirname($filename) : sprintf('%s/%s', dirname($filename), static::$_model_dir);
    is_dir($model_dir) or mkdir($model_dir, 0755, TRUE);

    $filename = sprintf('%s/%s', $model_dir, basename($filename));

    // easy way
    \Cli::write("\tCreating $type: $filename", 'green');
    @file_put_contents($filename, $contents);
    @chmod($filename, 0666);
  }
}
14
12
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
12