Fixing phpmyadmin not found problem and AllowNoPassword in ubuntu

Every time I installed phpmyadmin in my ubuntu desktop, navigating to http://localhost/phpmyadmin simply displays a 404 message. This is how I fix everytime -

$ sudo ln -s /usr/share/phpmyadmin /var/www

Fixing AllowNoPassword

I don’t use any password for mysql in my development invironment. But by default phpmyadmin doesn’t allow you to login without a password. You can overcome it by editing the /etc/phpmyadmin/config.inc.php. Open the file with root previledge -

$ sudo gedit /etc/phpmyadmin/config.inc.php

And uncomment this line

$cfg['Servers'][$i]['AllowNoPassword'] = TRUE;

Changing apache document root in ubuntu

In my development machine I always like to move the default /var/www directory to my home directory, e.g. /home/tareq/www . It’s very simple to do. Open the /etc/apache2/sites-available/default file with administrator previledge and change the document root as you want

$ sudo gedit /etc/apache2/sites-available/default

Now change the file like this:

DocumentRoot /home/tareq/www
<Directory />
    Options FollowSymLinks
    AllowOverride None
</Directory>
<Directory /home/tareq/www/>
    Options Indexes FollowSymLinks MultiViews
    AllowOverride None
    Order allow,deny
    allow from all
</Directory>

Now restart your apache

$ sudo /etc/init.d/apache2 restart

Update

According to Nasim vai, there is a more elegant solution with a single line command :-

$ sudo rm -r /var/www; sudo ln -s /home/${USER}/www /var/www

Deploying PHP apps with git and git submodule

I used to work in my projects like editing a file and uploading the changed files back to the server every time when it feels like those changes are OK. But when the number of files gets bigger, I loose track which files I’ve edited. In that case I had to upload all the files again to the server via FTP.

I am using Git as my primary SCM tool. Although I wasn’t using any SCM until I realized how essential it was when developing the plugin WP User Frontend. Some clients asked me to modify the plugin to fit in their project, others asked about other requirements. So every time I had to modify that plugin to suit their needs from the beginning. And It was a pain in the ass to track where I changed for that custom work. Because I had to update the plugin again to release in the public without the custom modification. So, it was a nightmare.

Anyway, back to the topic. I thought I can easily track those changed files and can only upload those change sets and it’ll be very tiny. So I am writing the process as a future reference for myself and might help others too.

1. initialize your project

$ mkdir awesome-project
$ cd awesome-project
$ git init

As I was also working with git submodules, I’ll add the submodule to my newly created awesome project. If you don’t know what a submodule is, it’s usually an another git repository that can be used under another git project.

2. Adding git submodule

$ git submodule add ~/www/tiny-framework lib/framework

Here I am using another git project ~/www/tiny-framework inside my awesome-project in path awesome-project/lib/framework. This command will clone my tiny-framework project in the awesome-project/lib/framework folder.

You can skip the submodule part if you are not using any.

3. pulling changes from the framework

In case you have updated your tiny-framework project, obviously you’ll want to bring the changes to your awesome-project too, but those changes will not automatically pulled down in your awesome project. You’ve to pull it manually.

$ cd lib/framework
$ git pull

Now you’ve worked in your project and ready to deploy to the server for test or production usage. It’s time to add a remote branch to your project.

4. Add remote repo to deploy the app

Now add a remote repository to your awesome project.

$ git remote add production ssh://example.com/~/git/app

I have shell access to my server, so I am adding the server as the remote repository. The trailing ~/git/app is the path where I’ll be pushing my local repo. In case you don’t know what the ~ sign means, it’s a shortcut to your home directory path.

5. Create the app bare repo in server

Now that you’ve added the remote repository to your local machine, you’ve to create the actual remote repository to the server. Log in to your server and create the folder and initialize the empty git repo.

$ mkdir git/app
$ cd git/app
$ git init --bare

You might have noticed, I am creating a bare repo here. There are some reasons behind why I am using bare repo.

The bare repo is not like a normal git repo, it doesn’t and will not contain any files that you’ll be pushing from your local repo. What we’ll be doing is :-

  • we will create a post-receive hook in this bare repo
  • we will push the local repo to this bare repo
  • the post-receive hook in this bare repo will checkout our local repo and will copy our local files to another folder in the server

6. Add post receive hook to the server

Now in this bare repo, we’ll add the post receive hook to checkout our local repo

$ cd hooks
$ vi post-receive.sample

7. Add the details of the folder to clone

You’ve to add this line in the post-receive.sample file. I am using vi/vim, you can you nano or emacs or whatever editor you want. But make sure you are providing the right path to the folder. In my case, my local repo will be copied to the awesome-project folder in public_html directory

GIT_WORK_TREE=~/public_html/awesome-project git checkout -f

8. Rename and make executable

To make the hook work, you’ve to rename the post-receive.sample file to post-receive and make it executable

$ mv post-receive.sample post-receive
$ chmod +x post-receive

9. Now push the changes

Now everything is done, we are finally able to push our local git repo to the server. The files will be placed in public_html/awesome-project folder in the server.

$ cd awesome-project
$ git push production master

Now, you might have noticed, the submodule has not been deployed to your server, why is that? Because git consider the submodule as another git repo and if you want to push the submodule too, you’ve to create an another bare repo in the server, configure the post-receive hook, adding the remote repo in the submodule and push them again as you did for your awesome-project, damn! But you’ve to do it :(

10. Push the submodule

Repeat the process 4 to 9 again. That means:

  1. cd into the “framework” folder
  2. add remote repo
  3. create bare repo in server (e.g: ~/git/framework)
  4. add the post-receive hook in path: ~/public_html/awesome-project/lib/framework
  5. push the local changes

Thats pretty much it.

Skipping the password prompt

Now your system is ready and you can always push your changes to the server. But, every time it’ll ask your ssh password when pushing the changes. You can skip this problem too. Generate a private/public key for your laptop/computer. Log in to your cpanel. Goto the SSH/Shell Access => Manage SSH Keys. Then import your public key and authorize it. From now on, you’ll not be asked to enter your password every time you push you changes.

Extra: Removing a git submodule

If you want/have to remove the submodule from the project, here’s how to do it

git rm --cached path/to/submodule

How to extend WP User Frontend

WP User Frontend plugin supports some actions and filters by itself. That means you can extend this plugin without touching it’s code. Lets see how to do that.

Adding a input field

You can add your custom input fields in 5 areas in the post add form, they are:

  • Top area: wpuf_add_post_form_top
  • Before the post description: wpuf_add_post_form_description
  • After the post description: wpuf_add_post_form_after_description
  • After the tags area: wpuf_add_post_form_tags and
  • At the bottom: wpuf_add_post_form_bottom

These are the action hooks and you can bind your function to display/process anything you want. Lets create a function that will add a text field before the post description area –

/**
 * Add a field to the add post area
 * 
 * @uses `wpuf_add_post_form_description` action hook
 * 
 * @param string $post_type the post type of the post add screen
 * @param object|null $post the post object
 */
function wpufe_artist( $post_type, $post = null) {
    
    $artist = ( $post != null ) ? get_post_meta( $post->ID, 'artists', true ) : '';
    ?>
    <li>
        <label for="song_artist">
            Artist <span class="required">*</span>
        </label>
        <input class="requiredField" value="<?php echo esc_attr( $artist ); ?>" type="text" name="song_artist" id="song_artist" minlength="2" />
        <div class="clear"></div>
    </li>
    <?php
}

And we can show this field by binding the function in any of those 5 action hooks mentioned before.

add_action( 'wpuf_add_post_form_description', 'wpufe_artist', 10, 2 );

These hooks can receive 2 parameters, the first one is the post_type and second one is the post object (only available on edit post area, otherwise set to NULL).

Validating the input

Now that we’ve added our field to the posting form area, we can validate that field if we want.

/**
 * Validate the artist name
 * 
 * @uses 'wpuf_add_post_validation' filter
 * 
 * @param array $errors errors array
 * @return array errors array
 */
function wpufe_artist_validation( $errors ) {
    if( $_POST['song_artist'] == '' ) {
        $errors[] = 'Please enter the artist name';
    }
    
    return $errors;
}
add_filter( 'wpuf_add_post_validation', 'wpufe_artist_validation' );

use the “wpuf_add_post_validation” filter for validating the input and return the errors.

Note: For a reason, the errors are hidden by default. That means, if any validation fails and return errors, you’ll not see the errors.

There is a line in “wpuf-add-post.php” like this:

//echo wpuf_error_msg( $errors ); 

it means the errors are not shown although if it has any. The reason behind this approach is to escape PHP’s “header already sent” message (for now).

for edit post validation, use this filter “wpuf_edit_post_validation” just like “wpuf_add_post_validation” filter

Processing the input

Now that you’ve validated the user input, it’s time to process the data.

There is a action hook wpuf_add_post_after_insert runs after the new post creation, it returns the post id. So you can grab the post ID and process as you want.

/**
 * Add the artist after new post creation
 * 
 * @uses `wpuf_add_post_after_insert` action hook
 * 
 * @param int $post_id the newly created post id
 */
function wpufe_add_artist( $post_id ) {
    update_post_meta( $post_id, 'artist', $_POST['song_artist'] );
}
add_action( 'wpuf_add_post_after_insert', 'wpufe_add_artist' );

for edit post area, use this action hook: “wpuf_edit_post_after_update

Other options

Modifying the new post arguments:

You can modify the post arguments before running the wp_insert_post( $args ) function. For example, if you want to change the post status forcefully -

/**
 * Modify the post array
 * 
 * @uses `wpuf_add_post_args` filter hook
 * 
 * @param array $my_post the post array
 * @return array the post array
 */
function wpufe_change_post_status( $my_post ) {
    $my_post['post_status'] = 'pending';
    
    //want to change the post author?
    $my_post['post_author'] = 1;
    
    //must return
    return $my_post;
}

add_filter( 'wpuf_add_post_args', 'wpufe_change_post_status' );

for edit post area, use this filter: “wpuf_edit_post_args

Redirecting after new post:

You can set the redirection url after the new post creation.

/**
 * Change the direction url
 * 
 * @uses `wpuf_after_post_redirect` filter hook
 * 
 * @param string $url the redirection url
 * return string new redirect url
 */
function wpufe_force_redirection( $url ) {
    return home_url('/dashboard/');
}
add_filter( 'wpuf_after_post_redirect', 'wpufe_force_redirection' );

Showing info on dashboard:

There is a hook on the plugin dashboard area wpuf_dashboard. It accepts two parameter, the user id and the currently showing post_type.

/**
 * Show in dashboard
 * 
 * @uses `wpuf_dashboard` action hook
 * 
 * @param int $user_id the current users user id
 * @param string $post_type
 */
function weufe_dashboard_info( $user_id, $post_type ) {
    $user = get_userdata( $user_id );
    
    echo 'Hello ' . $user->display_name . ', Having fun?';
}
add_action( 'wpuf_dashboard', 'weufe_dashboard_info', 10, 2 );

Disabling posting capability:

You can even block a specific user from posting and show him a message/cause. Helpful for blocking spammers.

Lets check if a user has a meta field “paid” with the value “yes”, so we can let the users posting who paid for something, others will see a message.

/**
 * Check if the current user can post
 * 
 * @return bool
 */
function wpufe_can_post() {
    $user = wp_get_current_user();
    $paid = get_user_meta( $user->ID, 'paid', true );
    
    if( $paid == 'yes' ) {
        return true;
    }
    
    return false;
}

/**
 * Block the user if hasn't the post capability
 * 
 * @return string
 */
function wpufe_block_user( $can_post ) {
    
    if( wpufe_can_post() ) {
        return 'yes';
    }
    
    return 'nope';
}
add_filter( 'wpuf_can_post', 'wpufe_block_user' );

/**
 * Show the message if can't post
 * 
 * @param string info message 
 * @return string info message
 */
function wpufe_show_message( $info ) {
    if( !wpufe_can_post() ) {
        $info = 'Sorry, you have to pay first';
    }
    
    return $info;
}
add_filter( 'wpuf_addpost_notice', 'wpufe_show_message' );

Modifying the plugin options

You can also change the plugin options and add your own options to the plugin settings area. Lets take a look how to add “EURO” as a currency in the plugin options area.

/**
 * Adds new currency to admin options
 * 
 * @param array $fields admin options
 */
function wpufe_currency_filter( $fields ) {
    
    foreach( $fields as $key => $val ) {
        if( $val['name'] == 'wpuf_sub_currency' ) {
            $fields[$key]['options']['EUR'] = 'EURO';
        }
    }
    
    return $fields;
}
add_filter( 'wpuf_build_form_args', 'wpufe_currency_filter' );

The plugin settings are build from a big array, so you can add/modify the array. So handy!