GitHub not accepting public SSH key: fix it by switching from HTTP(S) to SSH in the Git repository config

Submitted by Peter Majmesku on Mon, 08/29/2016 - 19:57

If you clone a Git repository from GitHub via the HTTPS URL, which is placed in the section as shown below, than your public SSH key will not be recognized by GitHub.

You can test your public SSH key for GitHub usage by the following command:

ssh -T git@github.com
GitHub

If you have chosen the wrong HTTPS option before (it must be SSH), you can fix that by the following steps.

  1. Open the file at .git/config
  2. Look for 
    url = http://github.com/path/to/repository or url = https://github.com/path/to/repository
  3. Replace it by
    url = ssh://git@github.com/path/to/repository
  4. Save the file and GitHub will accept the public SSH key on the next push. No username and password typing anymore.
Tags

Fix Line Endings Between Various File Systems

Submitted by Peter Majmesku on Mon, 08/29/2016 - 19:56

If you work sometimes on Windows, sometimes on Mac and sometimes on Linux, you can get troubles with line endings. Programs which aren't smart enough to detect line endings by them self, will display the text as if the file contained no line breaks at all.

  • Windows, and DOS before uses a pair of CR and LF characters to terminate lines
  • UNIX (Including Linux and FreeBSD) uses an LF character only. 
  • OS X also uses a single LF character 
  • Classic Mac operating system used a single CR character for line breaks. 

That's tricky. A tool for fixing line endings is "SFK - The Swiss File Knife File Tree Processor". It's mentioned at http://stackoverflow.com/questions/7068179/convert-line-endlings-for-whole-directory-tree-git/16886243#16886243.

All you have is to use the following command for converting to Mac OSX:

sfk remcr -dir your_project_directory

Git: Fixing "error: src refspec BRANCHNAME matches more than one."

Submitted by Peter Majmesku on Mon, 08/29/2016 - 19:50
Sometimes it happens, that there're more heads with the same name in the Git repository. That can happen by copy and pasting folders. To delete any duplicate head, the following command can be used.
git push origin --delete refs/heads/BRANCHNAME
Then the last command, which will bring it to work again:
git push origin BRANCHNAME
Tags

Yii2: Bring the assets from your module to your view

Submitted by Peter Majmesku on Mon, 08/29/2016 - 19:34

If you want to ship assets (JavaScript, CSS files) from your Yii2 module to your view, you can do that elegant with a couple of simple steps.

1., Folder structure

We assume that your Yii2 module is located at

/yii-base-folder/modules/YOUR-YII-MODULE-FOLDER

The assets are at

/yii-base-folder/modules/YOUR-YII-MODULE-FOLDER/assets

So the JavaScript files are at

/yii-base-folder/modules/YOUR-YII-MODULE-FOLDER/assets/js
 

2., Set an alias to your assets in your Module.php in your module (/yii-base-folder/modules/YOUR-YII-MODULE-FOLDER/Module.php)

namespace app\modules\MY-MODULE;
class 
Module extends \yii\base\Module
{
    public 
$controllerNamespace 'app\modules\MY-MODULE\controllers';
    public function 
init()
    {
        
parent::init();
        
$this->setAliases([
            
'@MY-MODULE-assets' => __DIR__ '/assets'
        
]);
    }

3., Put your asset class into your assets folder to setup your "assets bundle"

We name a bunch of assets "assets bundle". Here you declare your files and make it accessible to your view.

namespace app\modules\MY-MODULE\assets;
use 
yii\web\AssetBundle;
class 
MyModuleAsset extends AssetBundle
{
    
// the alias to your assets folder in your file system
    
public $sourcePath '@yiipass-assets';
    
// finally your files.. 
    
public $css = [
      
'css/first-css-file.css',
      
'css/second-css-file.css',
    ];
    public 
$js = [
      
'js/first-js-file.js',
      
'js/second-js-file.js',
    ];
    
// that are the dependecies, for makeing your Asset bundle work with Yii2 framework
    
public $depends = [
        
'yii\web\YiiAsset',
        
'yii\bootstrap\BootstrapAsset',
    ];

4., Now you can access your assets from your view

We assume that your view's index.php file is located at /yii-base-folder/modules/YOUR-MODULE/views/ANY-VIEWS-SUBFOLDER/index.php

// that class is usually used, if you work with html in your view.
use yii\helpers\Html;
// here comes your Yii2 asset's class!
use app\modules\YOUR-MODULE\assets\YOUR-ASSER-CLASS;
// now Yii puts your css and javascript files into your view's html.
MyModuleAsset::register($this);
?>

<p>
  Some <strong>HTML</strong> my <i>friend..</i> :)
</p> ?>

5., Conclusion

Now Yii2 puts your CSS and JavaScript files nicely into your HTML. By default the JavaScript files will be put nicely into the footer of your HTML. Also the CSS and JavaScript files will be copied into your web-accessible assets folder. The users from your webpage will not be allowed to get info about your Yii project folder structure. So the path to your JavaScript file will look like that: 

<script src="/assets/3598bbc6/js/YOUR-JavaScriptFile.js"></script

The path in your project's directory will be:
/YOUR-Yii2-PROJECT/web/assets/3598bbc6/js/YOUR-JavaScript-File.js

Also the PHP asset class will be copied from your module's folder:
/YOUR-Yii2-PROJECT/web/assets/3598bbc6/YourAssetsPhpClass.php

Don't forget to not modify the files at /YOUR-Yii2-PROJECT/web/assets/3598bbc6/ manually, because they're created automatically by the Yii2 framework.
 

6., Learn more

The "The Definitive Guide to Yii 2.0" is mostly the best first place to learn about Yii2. So you find more detailed information about the assets functionality at the assets chapter. I recommend also to read the excellent PHP class comments in the Yii2 core. Like f.e. /YOUR-Yii2-PROJECT/vendor/yiisoft/yii2/web/AssetBundle.php. Yii2 is one of the few OpenSource projects where the PHP code itself can often lead you to your goals.

Tags

MySQL: Import and Export (Compressed) Databases

Submitted by Peter Majmesku on Mon, 08/29/2016 - 19:24

The export (dump)

This command will generate you a compressed dump file with the date information in the filename.

mysqldump -u username -p"password" database_name | gzip > $(date +"%Y-%m-%d")-database_name.sql.gz

Import the database dump

Firstly make sure that the "empty" database exists. Then import it:

mysql -uUSERNAME -p"PASSWORD" database_name < dump-filename.sql

Import a Gzip compressed database dump file:

zcat database-dump-file.sql.gz | mysql -uroot -ppassword database-name

Your MySQL user has no LOCK TABLES permission

If you receive the error

mysqldump: Got error: 1044: Access denied for user 'my-user'@'localhost' to database 'my-database' when using LOCK TABLES

then your MySQL has not the permission to lock the database tables. This would guarantee, that you get an non-corrupted database dump. Because there were no write-queries while you're dumping the database. You can skip this error and risk a corrupted database dump (which might still work for development purposes) with the --skip-lock-tables option. Here is the full command as an example:

mysqldump -uUSERNAME -pPASSWORD --skip-lock-tables DATABASENAME | gzip > DATABASENAME.sql.gz

Tags

Yii2: Access your services within your module

Submitted by Peter Majmesku on Mon, 08/29/2016 - 19:22

There're some ways to declare the service in your config file for global use, but I wanted a way to setup my service in my module. Well, it took me a while so I write the way down here to look back in future to not search around the web.

Firstly you need to declare the service in your module:

namespace app\modules\MY-MODULE;
class 
Module extends \yii\base\Module
{
    public 
$controllerNamespace 'app\modules\MY-MODULE\controllers';
    public function 
init()
    {
        
parent::init();
        
// Declare services. Let's say you need the XmlService.
        
$this->set('xml', new services\XmlService());
    }

Afterwards you can access your module wherever you want to (note the cast for handier usage in your IDE):

/* @var $xml app\modules\yiipass\services\xml */
$xml = \Yii::$app->getModule('MY-MODULE')->get('xml'); 
Tags

Eclipse mit Plugins zur PHP IDE rüsten

Submitted by Peter Majmesku on Mon, 08/29/2016 - 19:20

Hallo zusammen,
da ihr viele meist Remote arbeitet und da auch eine PHP IDE nützlich ist, ist Eclipse nicht schlecht. Im Gegensatz zu Netbeans oder PhpStorm lädt Eclipse mit dem Remote System Explorer Plugin die Dateien nicht herunter. Zudem sind Calltips für PHP Befehle und das Springen zu Funktionsdeklarationen möglich (Remote sobald die Datei mit den Deklarationen einmal geöffnet wurde). Man springt z.B. mit STRG + Klick mit linker Maustaste auf Funktionsaufruf im Code. 

Das Cacheing der Deklarationen klappt mit dem letzten Punkt in der unten aufgeführten Anleitung. Probierts mal aus. Ist eine gute OpenSource IDE für PHP Entwicklung, gerade wenn ihr Remote arbeitet, nicht einzelne Projekte anlegen und den Code herunterladen wollt.

http://www.patrickjwaters.com/blog/2011-07-24/how-setup-eclipse-php-pdt-remote-system-explorer-theme-manager-and-drupal-plugins/35?page=1

Beim Umsetzen "das Ganze" Tutorial durchgehen. ;)

Tags

How to use PHPUnit fixtures in your Yii2 development

Submitted by Peter Majmesku on Mon, 08/29/2016 - 19:04

Often you need to create extra database data to run your PHPUnit test, when you're creating your application with Yii2 framework. The best is, that you're doing this work only once and save this with your test, so that you can re-use this test data on every test run. This data is called "fixtures". I want to introduce you my approach of using fixtures with CSV files, which are containing the data which will be written into your database, as you're fireing your PHPUnit test. For programming and running PHPUnit tests I prefer PhpStorm. But you can test your code also with PHPUnit by command line of some configuration in Netbeans or Eclipse with PHP configuration.

PhpMyAdmin and MySQL workbench are allowing you to export CSV files with your database data and the column-names in the first line of the export. The contents of the first line are the names of your properties, which are defined in your Yii model. Ok, let's say you have such exports, you need to have your PHPUnit test.

use app\tests\fixtures\ModelFixtureDataCreator;
class 
MyTest extends PHPUnit_Framework_TestCase
{
    protected function 
setUp()
    {
        require_once 
'yii_booter_for_tests.php';
        
$test_classname get_class($this);
        
ModelFixtureDataCreator::create($test_classname);
    }
    public function 
test()
    {
        
MyController::export(1);
    }
 

At the beginning you see, that I use the ModelFixtureDataCreator(); class for creating my fixtures for the PHPUnit test. The folder structure in my project is the same as in the namespace. I'll explain you the ModelFixtureDataCreator(); class later in detail. The first method in my test is setUp(); which works like a constructor in PHPUnit. I require a file which is booting Yii2 for me, so that I can use it in my unit tests.

if(is_numeric(strpos(getcwd(), '/tests'))){
    require_once 
getcwd() . '/../yii_boot_console.inc.php';
} else {
    require_once 
getcwd() . '/yii_boot_console.inc.php';

This code is very easy, it handles just the paths for me, so that I don't have to mind from which folder I start my tests. This file is just booting Yii's console application. It's just the file you use to run your Gii application from the command line.

I've modified it a bit for my needs (you're free to modify yours as you wish):

<?php defined('YII_DEBUG') or define('YII_DEBUG'true);
// fcgi doesn't have STDIN and STDOUT defined by default
defined('STDIN') or define('STDIN'fopen('php://stdin''r'));
defined('STDOUT') or define('STDOUT'fopen('php://stdout''w'));
require_once(
__DIR__ '/vendor/autoload.php');
require_once(
__DIR__ '/vendor/yiisoft/yii2/Yii.php');
use 
app\controllers\CmPlatformDeterminationClass;
defined('ENVIRONMENT') or define('ENVIRONMENT''dev');
if(!isset(
$argv)){
    
$argv false;
}
// the path to your config file.
$config = require_once('the/path/to/your/config/file.php');
new 
yii\console\Application($config); 

Then I determine the name of my test class and pass it finally to my ModelFixtureDataCreator(); class, where I call the create-method statically:

<?php $test_classname get_class($this);
ModelFixtureDataCreator::create($test_classname); 

The magic from the ModelFixtureDataCreator(); class is, that it uses "convention over configuration". Once you have the following folder structure the class is able to create all fixture data in relation to your test.

- your yii2 application folder
-- tests folder
--- fixtures folder
---- folder exactly named like your test without the file extension (f.e. ExportControllerTest)
----- the csv files exactly named like your models (f.e. MyModel.csv)

 Downwards you can see the code from ModelFixtureDataCreator(); class with it's comments.

<?php amespace app\tests\fixtures;

use 
yii\base\Exception;


/**
 * Class ModelFixtureDataCreator
 * @package app\tests\fixtures
 */
class ModelFixtureDataCreator {

    
/**
     * Reads the CSV files from the test related fixture folder, instantiates
     * the model by the CSV filename without the file-extension and passes
     * it to the writeFixtureDataForModelIntoDb(); method with the modelname
     * and the test classname.
     *
     * @param $test_classname
     */
    
public static function create($test_classname){
        
$path__fixture_folder 'fixtures/' $test_classname;

        
$handle__fixture_folder opendir($path__fixture_folder);

        while ((
$file readdir($handle__fixture_folder)) !== false){
            if(
is_file($path__fixture_folder '/' $file)){

                
$arr__pathinfo pathinfo($file);
                
$str__modelname str_replace('.' $arr__pathinfo['extension'],
                                                                    
''$file);

                
$str__modelpath 'app\\models\\' $str__modelname;

                
$obj__model_instance = new $str__modelpath;
                
self::writeFixtureDataForModelIntoDb($obj__model_instance,
                                            
$str__modelname$test_classname);
            }

        }

    }

    
/**
     * Uses the first line from the CSV file as the model properties. Then
     * the method treats the next lines as values and writes them to the model
     * related database table.
     *
     * @param $obj__model_instance
     * @param $str__modelname
     * @param $test_classname
     */
    
private static function writeFixtureDataForModelIntoDb($obj__model_instance,
                                            
$str__modelname$test_classname){

        
$fp fopen("fixtures/$test_classname/$str__modelname'.csv''r');

        
$first_row_runed false;
        
$properties = array();
        while ((
$data fgetcsv($fp1000",")) !== FALSE) {
            if(
$first_row_runed === false){
                
$properties $data;
            } else {
                
$sub_counter 0;
                foreach(
$data as $d){
                    
$obj__model_instance->$properties[$sub_counter] = $d;
                    
$sub_counter++;
                }
                
$obj__model_instance->save();
            }

            
$first_row_runed true;
        }

    }


The class is currently only writing fixture data into your database. By the tearDown(); method from your PHPUnit test you're able to implement logic, which is deleting the fixture data after your test has been runned.

Do you have any ideas for this approach? Share them!