Category Archives: PHP

Protected: Làm dự án wordpress 4.9.x

This content is password protected. To view it please enter your password below:

Advertisements

Simple Captcha in PHP

This captcha is simple and can use for any website ^^

<?php
require_once BASE_PATH . '/Code/claviska/simple-php-captcha.php';
class Captcha {
    /**
     * Document: https://github.com/claviska/simple-php-captcha
     */
    public static function checkCaptcha () {
        $isSuccess = FALSE;
        if (
            empty($_POST['simple_captcha_client']) === FALSE &&
            empty($_SESSION['simpleCaptcha']['code']) === FALSE &&
            strtolower($_POST['simple_captcha_client']) == strtolower($_SESSION['simpleCaptcha']['code'])
        ) {
            $isSuccess = TRUE;
        }
        return $isSuccess;
    }
    public static function generateCaptcha () {
        $_SESSION['simpleCaptcha'] = simple_php_captcha([
            'min_length' => 6,
            'max_length' => 6,
            'characters' => '123456789'
        ]);
        return $_SESSION['simpleCaptcha']['image_src'];
    }
    public static function showCaptcha ($class = NULL) {
        return '<div class="captcha-holder ' . $class . '"><img src="' . Captcha::generateCaptcha() . '" class="captcha-img" /><input type="text" name="simple_captcha_client" placeholder="' . convertCase(trans('validation.enter_captcha'), 3) . '" /><a data-href="' . BASE_URL . '/captcha/reset" class="captcha-refresh"><i class="icons fi-refresh"></i></a></div>';
    }
}
class Default_CaptchaController {
    function resetAction() {
        require_once BASE_PATH . '/Code/Captcha.php';
        echo Captcha::generateCaptcha();
    }
}
$('.captcha-refresh').on('click', function () {
	var $me = $(this);
	$.ajax({
		url: $(this).data('href')
	})
	.done(function(src) {
		$me.closest('.captcha-holder').find('.captcha-img').attr('src', src);
	});
});
.captcha-holder {
    &> * {
        display: inline-block;
        width: auto;
        height: 39px;
    }
    &> input {
        width: 125px;
    }
    .captcha-refresh {
        cursor: pointer;
        .icons {
            @include font-size(22px);
            margin-left: 5px;
            position: relative;
            top: 3px;
        }
    }
}

Continue reading Simple Captcha in PHP

Login bằng php-jwt thay cho session, cookie truyền thống

install:

composer require firebase/php-jwt:dev-master
composer require zendframework/zend-config:~2.3
composer require zendframework/zend-http:~2.3

Tham khảo: sitepoint Continue reading Login bằng php-jwt thay cho session, cookie truyền thống

Gulp run as series of tasks

// task cleanDist
gulp.task('cleanDist', function(cb) {
  return del([
    './www/js/configuration.js'
  ]);
});
// task copy-local-files: require 'cleanDist' task
gulp.task('copy-local-files', ['cleanDist'], function(cb) {
  return gulp.src('./../config/local/**/*').pipe(gulp.dest('./www'));
});
// task lint: require 'copy-local-file' task
gulp.task('lint', ['copy-local-files'], function() {
  return gulp.src(paths.js)
    .pipe(jshint('.jshintrc'))
    .pipe(jshint.reporter('jshint-stylish'));
});

Bonus: Ionic run task before server and after serve: config in ionic.project file

{
  "name": "songpham",
  "app_id": "20002005",
  "gulpDependantTasks": [ // before serve
    "lint"
  ],
  "gulpStartupTasks": [ // after serve
    "watch"
  ],
  "watchPatterns": [
    "www/**/*",
    "!www/lib/**/*"
  ]
}

Apache/Nginx/Xampp apache enable CORS Access-Control-Allow-Origin for Angular Js

More information, you should check here: https://en.wikipedia.org/wiki/Cross-origin_resource_sharing
How CORS works:
1
The browser sends the OPTIONS request with an Origin HTTP header. The value of this header is the domain that served the parent page. When a page from http://www.foo.com attempts to access a user’s data in bar.com, the following request header would be sent to bar.com:

Origin: http://www.foo.com

The server may respond with:
An Access-Control-Allow-Origin (ACAO) header in its response indicating which origin sites are allowed. For example:

Access-Control-Allow-Origin: http://www.foo.com

Preflight example
When performing certain types of cross-domain AJAX requests, modern browsers that support CORS will insert an extra “preflight” request to determine whether they have permission to perform the action.

OPTIONS /
Host: bar.com
Origin: http://foo.com

If bar.com is willing to accept the action, it may respond with the following headers:

Access-Control-Allow-Origin: http://foo.com
Access-Control-Allow-Methods: PUT, DELETE

Continue reading Apache/Nginx/Xampp apache enable CORS Access-Control-Allow-Origin for Angular Js

Set up browser-sync with Gulp

var gulp = require('gulp'),
    browserSync  = require('browser-sync').create(),
    gulpif       = require('gulp-if'),
    gutil        = require('gulp-util'),
    uglify       = require('gulp-uglify'),
    concat       = require('gulp-concat'),
    cssmin       = require('gulp-cssmin'),
    sass         = require('gulp-sass'),
    sourcemaps   = require('gulp-sourcemaps'),
    plumber      = require('gulp-plumber');
var errorHandle = function (error) {
    gutil.log(gutil.colors.red(error.message));
    this.emit('end');
};
var production = false;
/**
 * Copy any needed files
 * Do a 'gulp copyfiles' after bower updates
 **/
gulp.task("copyfiles", function() {
    ...
});
var paths = {};
paths.scripts_1 = [
    ...
];
paths.scripts_2 = [
    ...
];
paths.scripts_3 = [
    ...
];
paths.css_1 = [
    ...
];
paths.css_2 = [
    ...
];
gulp.task('buildVendorJs', function() {
  return gulp.src(paths.scripts_1)
      .pipe(plumber(errorHandle)) /* replaces pipe method and removes standard onerror handler on error event */
      .pipe(sourcemaps.init())
      .pipe(concat('vendors.js'))
      .pipe(gulpif(production, uglify({ mangle: false })))
      .pipe(sourcemaps.write('./'))
      .pipe(gulp.dest('./public/assets/js'));
});
gulp.task('buildAppJs', function() {
  return ...;
});
gulp.task('buildLangJs', function() {
  return ...;
});
gulp.task('buildVendorCss', function() {
  return gulp.src(paths.css_1)
      .pipe(plumber(errorHandle)) /* replaces pipe method and removes standard onerror handler on error event */
      .pipe(sourcemaps.init())
      .pipe(concat('vendors.css'))
      .pipe(sass())
      .pipe(gulpif(production, cssmin()))
      .pipe(sourcemaps.write('./'))
      .pipe(gulp.dest('./public/assets/css'));
});
gulp.task('buildAppCss', function() {
  return ...;
});
gulp.task('default', ['buildVendorJs', 'buildAppJs', 'buildLangJs', 'buildVendorCss', 'buildAppCss'], function () {
  browserSync.init({
      proxy:      'my.app'
  });
  gulp.watch(paths.scripts_1, ['buildVendorJs', browserSync.reload]);
  gulp.watch(paths.scripts_2, ['buildAppJs', browserSync.reload]);
  gulp.watch(paths.scripts_3, ['buildLangJs', browserSync.reload]);
  gulp.watch(paths.css_1, ['buildVendorCss', browserSync.reload]);
  gulp.watch(paths.css_2, ['buildAppCss', browserSync.reload]);
  gulp.watch([
    'app/Http/**/*',
    'app/Library/**/*',
    'app/Models/**/*',
    'app/*',
    'resources/views/**/*'
  ], browserSync.reload);
});

Using Yield in PHP to generate the combobox values

Generators will allow you to load tiny amounts of the total data at once.

/**
 * input: prependItemToArrayCombobox(array('' => 'Select Value'), array(1 => 'US', 2 => 'VN'));
 * output: Object ('' => 'Select Value', 1 => 'US', 2 => 'VN' )
 */
function prependItemToArrayCombobox ($result, $array) {
  if (empty($array) === FALSE) { /* add new items to the first if have */
    foreach ($array as $key => $value) {
      if (array_key_exists($key, $result) === FALSE) {
        yield $key => $value;
      }
    }
    foreach ($result as $key => $value) {
      yield $key => $value;
    }
  } else {
    if (empty($result) === FALSE) {
      foreach ($result as $key => $value) {
        yield $key => $value;
      }
    }
  }
}

Basic Javascript App

Let’s start on adding some JavaScript to make the app:

var Gimmie = {
    $content: $('.content'),
    $form: $('form'),
    toggleLoading: function(){
        // Toggle loading indicator
        this.$content.toggleClass('content--loading');

        // Toggle the submit button so we don't get double submissions
        // http://stackoverflow.com/questions/4702000/toggle-input-disabled-attribute-using-jquery
        this.$form.find('button').prop('disabled', function(i, v) { return !v; });
    },
    userInput: '',
    userInputIsValid: false,
    appId: '',
    validate: function() {
        // Use regex to test if input is valid. It's valid if:
        // 1. It begins with 'http://itunes'
        // 2. It has '/id' followed by digits in the string somewhere
        var regUrl = /^(http|https):\/\/itunes/;
        var regId = /\/id(\d+)/i;
        if ( regUrl.test(this.userInput) && regId.test(this.userInput) ) {
            this.userInputIsValid = true;
            var id = regId.exec(this.userInput);
            this.appId = id[1];
        } else {
            this.userInputIsValid = false;
            this.appId = '';
        }
    },
    throwError: function(header, text){
        // Remove animation class
        this.$content.removeClass('content--error-pop');
        // Trigger reflow
        // https://css-tricks.com/restart-css-animation/
        this.$content[0].offsetWidth = this.$content[0].offsetWidth;
        // Add classes and content
        this.$content
            .html('<p><strong>' + header + '</strong> ' + text + '</p>')
            .addClass('content--error content--error-pop');
        this.toggleLoading();
    },
    render: function(response){
        var icon = new Image();
        icon.src = response.artworkUrl512;
        icon.onload = function() {
            Gimmie.$content
                .html(this)
                .append('<p><strong>' + response.trackName + '</strong> Actual icon dimensions: ' + this.naturalWidth + '×' + this.naturalHeight + '</p>')
                .removeClass('content--error');
            Gimmie.toggleLoading();
            // If it's an iOS icon, load the mask too
            if(response.kind != 'mac-software') {
                var mask = new Image();
                mask.src = 'assets/img/icon-mask.png';
                mask.onload = function() {
                    Gimmie.$content.prepend(this);
                }
            }
        }
    }
};
$(document).ready(function(){
    e.preventDefault();
    // On page load, execute this...
    Gimmie.toggleLoading(); // call the loading function
    Gimmie.userInput = $(this).find('input').val();
    Gimmie.validate();
    if( Gimmie.userInputIsValid ) {
        /* make API request */
        $.ajax({
            url: "https://itunes.apple.com/lookup?id=" + Gimmie.appId,
            dataType: 'JSONP'
        })
        .done(function(response) {
            // when finished
            var response = response.results[0];
            if(response && response.artworkUrl512 != null){
                Gimmie.render(response);
            } else {
                Gimmie.throwError(
                    'Invalid Response',
                    'The request you made appears to not have an associated icon. <br> Try a different URL.'
                );
            }
        })
        .fail(function(data) {
            // when request fails
            Gimmie.throwError(
                'iTunes API Error',
                'There was an error retrieving the info. Check the iTunes URL or try again later.'
            );
        });
    } else {
        /* throw an error */
        Gimmie.throwError(
            'Invalid Link',
            'You must submit a standard iTunes store link with an ID, i.e. <br> <a href="https://itunes.apple.com/us/app/twitter/id333903271?mt=8">https://itunes.apple.com/us/app/twitter/<em>id333903271</em>?mt=8</a>'
        );
    }
});