MediaWiki, Parsoid and Heroku configuration hints

(MediaWiki 1.31.0)

Login “Remember password” checked by default

Add to LocalSettings.php:

$wgHooks['AuthChangeFormFields'][] = function ($requests, $fieldInfo, &$formDescriptor, $action) {
    $formDescriptor['rememberMe']['default'] = true;
    return true;
};

See Hooks/AuthChangeFormFields and HTMLForm.

However, if you need it because of random session drops then see the next chapter:

Session handling / PHP’s default session handler / Session problems

$wgSessionsInObjectCache vs $wgPHPSessionHandling

The first one (and setting it to false) is deprecated (= no longer has effect).

In case you’re getting randomly logged out or “a loss of session data” errors appear then try to disable mixing session handling of MW and PHP. Add to LocalSettings.php:

$wgPHPSessionHandling = 'disable';

Wake Parsoid on user login if running on Heroku free dynos

Parsoid is a node.js-based service used by MediaWiki’s awesome VisualEditor. Parsoid can be set up on a free Heroku account.

Add to LocalSettings.php:

$wgHooks['UserLoggedIn'][] = function($user) {
    if ($user->isAllowed('edit')) {

        $parsoid_host = 'parsoidonheroku.herokuapp.com';

        $fp = fsockopen('ssl://' . $parsoid_host, 443, $errno, $errstr, 30);
        $out = "GET / HTTP/1.1\r\n";
        $out .= "Host: " . $parsoid_host . "\r\n";
        $out .= "Content-Length: 0"."\r\n";
        $out .= "Connection: Close\r\n\r\n";
        fwrite($fp, $out);
        fclose($fp);
    }
};

After a user with edit permission logs into MediaWiki, sends a GET request to Parsoid Heroku-URL but doesn’t wait for an answer. Shouldn’t affect login time but decreases VisualEditor’s first-load time (otherwise could be ~20+ seconds). Free dynos go to sleep after 30min of inactivity. Currently maximum allowed awake time per 24h is 18h.

Enable local Parsoid to have edit access without hardcoding IP or cookie forwarding

Might be useful, depends on your server config. Add to LocalSettings.php:

if ($_SERVER['REMOTE_ADDR'] == gethostbyname(trim(`hostname`))) {
    $wgGroupPermissions['*']['read'] = true;
    $wgGroupPermissions['*']['edit'] = true;
    $wgGroupPermissions['*']['upload'] = true;
    $wgGroupPermissions['*']['reupload'] = true;
    $wgGroupPermissions['*']['reupload-shared'] = true;
}

Fix Jasny File Input in Avant theme and IE / MS Edge

Applies to “Avant – Clean and Responsive Bootstrap 3.3.2 Admin” or Avant 1.4 (c) 2015 as written in readme.txt.

Open /HTML/assets/css/styles.css, find the following block:

.btn-file > input {
  position: absolute;
  top: 0;
  right: 0;
  margin: 0;
  opacity: 0;
  filter: alpha(opacity=0);
  transform: translate(-300px, 0) scale(4);
  -webkit-transform: translate(-300px, 0) scale(4);
  font-size: 23px;
  height: 100%;
  width: 100%;
  direction: ltr;
  cursor: pointer;
}

Comment out the following lines:

/*  transform: translate(-300px, 0) scale(4);
  -webkit-transform: translate(-300px, 0) scale(4); */

Now Select file/image etc buttons should work in Internet Explorer 11 (as tested on 11.306.10586.0) and Microsoft Edge.

To make the examples in File Inputs section of the Form Components page work, open /HTML/form-components.htm and change:

<script type='text/javascript' src='assets/plugins/form-jasnyupload/fileinput.min.js'></script>

to:

<script type='text/javascript' src='assets/plugins/form-jasnyupload/fileinput.js'></script>

Now the controls and image preview are functioning.

Additionally the plugin could be upgraded to a more recent version, select “Download source code” and replace /HTML/assets/plugins/form-jasnyupload/fileinput.js and fileinput.less files with the ones from the downloaded archive. Upgrading to 3.1.3 makes “too much recursion”-errors disappear from the JS-console.

Android apk keystore signing for store

Keystore

First think you need to do is to generate keystore file for project. Store apps needs to be signed with that and its always good to have separated keystore for each app. Keep that securely cause you need this everytime youre updating your app on store.

You can generate also using various IDEs like NetBeans, Eclipse, Android Studio and so on, but in this time we’re using command line.

user@host:~/home $ keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000

Signing

After you have built your apk (unsigned) you need to use following command to sign this with previously generated keystore.

user@host:~/home $ jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore my_application.apk alias_name

Validate signed apk:

user@host:~/home $ jarsigner -verify -verbose -certs my_application.apk

Align

Finally align you apk to optimize it and after that it’s ready to be submitted into store.

user@host:~/home $ zipalign -v 4 my_application.apk my_application_aligned.apk

 

Using IF condition in SELECT in Active Record SQL scope (for Yii)

Instead of a string value use an array to specify different ‘select’ expressions (just a string will get exploded using comma as delimter and there’ll be an error). NB! New variables defined only in SQL query code (with AS) should be defined also in the Model:

// AR variables defined in SQL query code
public $begins_same_day;
public $is_long;

public function scopes()
{
	return array(
		'more' => array(
			'select' => array(
				'*',
				'FALSE AS begins_same_day',
				'IF (DATE(date_to) > DATE(date_from + INTERVAL 1 DAY), TRUE, FALSE) AS is_long'
			),
			'condition' => 'TO_DAYS(date(date_from)) > (TO_DAYS(date(NOW())) + 2)',
			'order' => 'date_from ASC, date_to ASC',
			'limit' => 20
		)
	);
}

Add custom fields under wp general settings

To add custom fields under wordpress general settings without hacking core code use this as example. Of course you can make it better and write some fancy class for doing this.

add_filter('admin_init', 'my_general_settings_register_fields');

function my_general_settings_register_fields()
{
	register_setting('general', 'my_field', 'esc_attr');
	add_settings_field('my_field', '<label for="my_field">'.__('My Field' , 'my_field' ).'</label>' , 'my_general_settings_fields_html', 'general');
}

function my_general_settings_fields_html()
{
	$value = get_option( 'my_field', '' );
	echo '<input type="text" id="my_field" name="my_field" value="' . $value . '" />';
}

WordPress custom menu display

Just a small example of how to build custom menu output in WordPress.

$menu_args		= array('menu' => 'Main menu', 'echo' => 0) ;
$menu_string	= wp_nav_menu($menu_args);
$xml	= new SimpleXMLElement($menu_string);
$out	= false;

foreach ($xml->ul[0] as $li) 
{
	$classes = array('current-page-ancestor', 'current-menu-item', 'current-menu-parent');
	if (strstr($li['class'], 'current-page-ancestor') || 
		strstr($li['class'], 'current-menu-item') || 
		strstr($li['class'], 'current-menu-parent')) 
	{
		$out = $li->ul;      
		$i = 0;
		if (isset($out->li) && !empty($out->li))
		{
			$out['id']		= 'sub_menu';
			$out['class']	= 'clear';
			foreach ($out->li as $li_sub) 
			{      
				if (!strstr($li_sub['class'], 'current-page-ancestor') && 
					!strstr($li_sub['class'], 'current-menu-item') && 
					!strstr($li_sub['class'], 'current-menu-parent')) 
				{
					unset($out->li[$i]->ul);
				}
				$i++;
			}
		}
		break;;
	}
}
if (!empty($out)) {
	 echo $out->asXML(); 
}

Replace menu links in Drupal 7 using menu_link & menu_tree hooks

Want to add span elements to menu, change ul id or add classes? Need images in menu or some custom style? You can do that by using menu_link for menu items and menu_tree hook for menus itself. To replace all menus remove __MENUNAME.

// Customize menu li & links
function MYTHEME_menu_link__MENUNAME($variables) 
{
	$element	= $variables['element'];
	$sub_menu	= '';

	if ($element['#below']) {
		$sub_menu = drupal_render($element['#below']);
	}

	// Enable this to use html in title, eg img, span or something else...
	$element['#localized_options']['html'] = true;

	$link = l('<span>' . $element['#title'] . '</span>', $element['#href'], $element['#localized_options']);

	return '<li' . drupal_attributes($element['#attributes']) . '>' . $link . $sub_menu . "</li>\n";
}

// Customize menu ul
function MYTHEME_menu_tree__MENUNAME($variables) 
{
	// Change id of menu ul
	return '<ul id="my-custom-menu-id">' . $variables['tree'] . '</ul>';
}

You can probably use preprocess_menu_link or preprocess_links as well, but this seems to be easiest way. Read more about it here.