Determing the namespace in a mediawiki page (api quest.) - php

For starters I must admit my PHP skills are pathetic (been doing this for 3 days)
I have during the last three days heavily modified an extension which parses pages just edited in mediawiki. The original purpose was to parse the page for text matching the names of other pages in the database, and autolink them. But it would only perform this function in the 'Main' namespace (namespace 0). I have modified it to parse for links across namespaces, using a weighted White-List of namespaces. (Weighted as in first come first serve based on the location in the white list. If white list is Development, Rules the Development trumps rules.)
I would like to further modify the extension to prioritize the current page's namespace by pushing it onto the front of the white list array, and to determine the current users group affiliations so as to further modify the priority list.
Determine the users group affiliations
Determine the current page's namespace SOLVED $var=$article->getTitle()->getNamespace();
Push the value to the front of the array SOLVED array_unshift($hastack, $needle);
I would greatly appreciate it if someone could point me to a site explaining at least the first two things. (The mediawiki community has thus far been less than useful)
If you offer up a code example please try to keep it stupidproof, I am that new to this {{shrug}} (Meaning keep the code samples php simple...it's extensible so there is always a better way, but I am not familiar with the extra modules.)
MediaWiki version in question is 1.21 (current stable as of 7-2013)
NOTE: For some reason the code isn't displaying right, but no lines were lost.
The array for the whitelist is defined as:
$wgLinkTitlesNamespaceWhitelist = array(5000, 5002, 5004, 5006,0);
Main file LinkTitles5000_body,php
if ( !defined( 'MEDIAWIKI' ) ) {
die( 'Not an entry point.' );
}
/*
function dump($var) {
error_log(print_r($var, TRUE) . "\n", 3, 'php://stderr');
};
*/
class LinkTitles_5000 {
static $safeTitle;
/// Setup function, hooks the extension's functions to MediaWiki events.
public static function setup() {
global $wgLinkTitlesParseOnEdit;
global $wgLinkTitlesParseOnRender;
global $wgHooks;
if ( $wgLinkTitlesParseOnEdit ) {
$wgHooks['ArticleSave'][] = 'LinkTitles_5000::onArticleSave';
};
if ( $wgLinkTitlesParseOnRender ) {
$wgHooks['ArticleAfterFetchContent'][] = 'LinkTitles_5000::onArticleAfterFetchContent';
};
$wgHooks['ParserBeforeTidy'][] = 'LinkTitles_5000::removeMagicWord';
}
/// This function is hooked to the ArticleSave event.
/// It will be called whenever a page is about to be
/// saved.
public static function onArticleSave( &$article, &$user, &$text, &$summary,
$minor, $watchthis, $sectionanchor, &$flags, &$status ) {
// To prevent time-consuming parsing of the page whenever
// it is edited and saved, we only parse it if the flag
// 'minor edits' is not set.
return $minor or self::parseContent( $article, $text );
}
/// Called when an ArticleAfterFetchContent event occurs; this requires the
/// $wgLinkTitlesParseOnRender option to be set to 'true'
public static function onArticleAfterFetchContent( &$article, &$content ) {
// The ArticleAfterFetchContent event is triggered whenever page content
// is retrieved from the database, i.e. also for editing etc.
// Therefore we access the global $action variabl to only parse the
// content when the page is viewed.
global $action;
if ( in_array( $action, array('view', 'render', 'purge') ) ) {
self::parseContent( $article, $content );
};
return true;
}
/// This function performs the actual parsing of the content.
static function parseContent( &$article, &$text ) {
// If the page contains the magic word '__NOAUTOLINKS__', do not parse
// the content.
$mw = MagicWord::get('MAG_LINKTITLES_TERMINOLOGY_NOAUTOLINKS');
if ( $mw -> match( $text ) ) {
return true;
}
// Configuration variables need to be defined here as globals.
global $wgLinkTitlesPreferShortTitles;
global $wgLinkTitlesMinimumTitleLength;
global $wgLinkTitlesParseHeadings;
global $wgLinkTitlesBlackList;
global $wgLinkTitlesSkipTemplates;
global $wgLinkTitlesFirstOnly;
global $wgLinkTitlesWordStartOnly;
global $wgLinkTitlesWordEndOnly;
// global $wgLinkTitlesIgnoreCase;
global $wgLinkTitlesSmartMode;
global $wgCapitalLinks;
global $wgLinkTitlesNamespaceWhitelist;
global $wgExtraNamespaces;
( $wgLinkTitlesWordStartOnly ) ? $wordStartDelim = '\b' : $wordStartDelim = '';
( $wgLinkTitlesWordEndOnly ) ? $wordEndDelim = '\b' : $wordEndDelim = '';
// ( $wgLinkTitlesIgnoreCase ) ? $regexModifier = 'i' : $regexModifier = '';
// To prevent adding self-references, we now
// extract the current page's title.
$myTitle = $article->getTitle()->getText();
( $wgLinkTitlesPreferShortTitles ) ? $sort_order = 'ASC' : $sort_order = 'DESC';
( $wgLinkTitlesFirstOnly ) ? $limit = 1 : $limit = -1;
if ( $wgLinkTitlesSkipTemplates )
{
$templatesDelimiter = '{{.+}}';
} else {
$templatesDelimiter = '{{[^|]+?}}|{{.+\|';
};
// Build a regular expression that will capture existing wiki links ("[[...]]"),
// wiki headings ("= ... =", "== ... ==" etc.),
// urls ("http://example.com", "[http://example.com]", "[http://example.com Description]",
// and email addresses ("mail#example.com").
// Since there is a user option to skip headings, we make this part of the expression
// optional. Note that in order to use preg_split(), it is important to have only one
// capturing subpattern (which precludes the use of conditional subpatterns).
( $wgLinkTitlesParseHeadings ) ? $delimiter = '' : $delimiter = '=+.+?=+|';
$urlPattern = '[a-z]+?\:\/\/(?:\S+\.)+\S+(?:\/.*)?';
$delimiter = '/(' . $delimiter . '\[\[.*?\]\]|' . $templatesDelimiter .
'|\[' . $urlPattern . '\s.+?\]|'. $urlPattern .
'(?=\s|$)|(?<=\b)\S+\#(?:\S+\.)+\S+(?=\b))/i';
$black_list = str_replace( '_', ' ',
'("' . implode( '", "',$wgLinkTitlesBlackList ) . '")' );
// Depending on the global setting $wgCapitalLinks, we need
// different callback functions further down.
if ( $wgCapitalLinks ) {
$callBack = "LinkTitles_5000::CallBackCaseInsensitive";
} else {
$callBack = "LinkTitles_5000::CallBackCaseSensitive";
}
# Added to suuport $wgLinkTitlesNamespaceWhitelist
foreach ($wgLinkTitlesNamespaceWhitelist as $LT_namespace){
# Create the link part reflecting NameSpace:
# if namespace is main (0) set to empty string
if ($LT_namespace === 0){
$LT_namespacePart = "";
} else {
$LT_namespacePart = str_replace('_', ' ', $wgExtraNamespaces[(int)$LT_namespace]);
$LT_namespacePart = $LT_namespacePart . ":";
}
# ===
// Build an SQL query and fetch all page titles ordered
// by length from shortest to longest.
// Only titles from 'normal' pages (namespace uid = 0)
// are returned.
$dbr = wfGetDB( DB_SLAVE );
# modified to suuport $wgLinkTitlesNamespaceWhitelist
# 'page_namespace = 0' becomes 'page_namespace = ' . $LT_namespace,
# ===
$res = $dbr->select(
$wgDBprefix . 'page',
'page_title, page_namespace',
array(
'page_namespace = ' . strval($LT_namespace),
'CHAR_LENGTH(page_title) >= ' . $wgLinkTitlesMinimumTitleLength,
'page_title NOT IN ' . $black_list,
),
__METHOD__,
array( 'ORDER BY' => 'CHAR_LENGTH(page_title) ' . $sort_order )
);
// Iterate through the page titles
foreach( $res as $row ) {
// Page titles are stored in the database with spaces
// replaced by underscores. Therefore we now convert
// the underscores back to spaces.
$title = str_replace('_', ' ', $row->page_title);
if ( $title != $myTitle ) {
LinkTitles_5000::$safeTitle = str_replace( '/', '\/', $title );
# add this to skip the function if more than 1 level of sub pages
# Thus if 0 or 1 "\/" is found we continue and process the entry
# if two or more are found we go AARRRRRGGGGHHHHH and skip it!
if (substr_count(LinkTitles_5000::$safeTitle, '\/') >1) {
continue;
}
# adding this to allow for sub pages to be broken into their parts
$LT5000_pos = strpos(LinkTitles_5000::$safeTitle, "\/");
if ($LT5000_pos !== false){
$LT5000_front = substr(LinkTitles_5000::$safeTitle, 0, $LT5000_pos);
$LT5000_back = substr(LinkTitles_5000::$safeTitle, $LT5000_pos+1);
LinkTitles_5000::$safeTitle = substr($title, $LT5000_pos+1);
} else {
$LT5000_back = '';
$LT5000_front = LinkTitles_5000::$safeTitle;;
}
// split the string by [[...]] groups
// credits to inhan # StackOverflow for suggesting preg_split
// see http://stackoverflow.com/questions/10672286
$arr = preg_split( $delimiter, $text, -1, PREG_SPLIT_DELIM_CAPTURE );
// Depending on the global configuration setting $wgCapitalLinks,
// the title has to be searched for either in a strictly case-sensitive
// way, or in a 'fuzzy' way where the first letter of the title may
// be either case.
if ( $wgCapitalLinks ) {
$searchTerm = '((?i)' . LinkTitles_5000::$safeTitle[0] . '(?-i)' .
substr(LinkTitles_5000::$safeTitle, 1) . ')';
} else {
$searchTerm = '(' . LinkTitles_5000::$safeTitle . ')';
}
$LT5000_out = "[[" . $LT_namespacePart . $title . "|";
for ( $i = 0; $i < count( $arr ); $i+=2 ) {
// even indexes will point to text that is not enclosed by brackets
$arr[$i] = preg_replace( '/(?<![\:\.\#\/\?\&])' .
$wordStartDelim . $searchTerm . $wordEndDelim . '/',
$LT5000_out.'$1]]', $arr[$i], $limit, $count );
if (( $limit >= 0 ) && ( $count > 0 )) {
break;
};
};
$text = implode( '', $arr );
// If smart mode is turned on, the extension will perform a second
// pass on the page and add links with aliases where the case does
// not match.
if ($wgLinkTitlesSmartMode) {
// split the string by [[...]] groups
// credits to inhan # StackOverflow for suggesting preg_split
// see http://stackoverflow.com/questions/10672286
$arr = preg_split( $delimiter, $text, -1, PREG_SPLIT_DELIM_CAPTURE );
for ( $i = 0; $i < count( $arr ); $i+=2 ) {
// even indexes will point to text that is not enclosed by brackets
$arr[$i] = preg_replace_callback( '/(?<![\:\.\#\/\?\&])' .
$wordStartDelim . '(' . LinkTitles_5000::$safeTitle . ')' .
$wordEndDelim . '/i', $callBack, $arr[$i], $limit, $count );
if (( $limit >= 0 ) && ( $count > 0 )) {
break;
};
};
$text = implode( '', $arr );
}
}; // if $title != $myTitle
}; // foreach $res as $row
}; // foreach $wgLinkTitlesNamespaceWhitelist as $LT_namespace
return true;
}
static function CallBackCaseInsensitive($matches) {
if ($LT5000_pos !== false){
# this if a / was found in the first place
$LT5000_call_out = $LT_namespacePart . $LT5000_front . '/' . $LT5000_back;
} else {
# this if there was no slash
$LT5000_call_out = $LT_namespacePart . $matches[0];
}
if ( strcmp(substr(LinkTitles_5000::$safeTitle, 1), substr($matches[0], 1)) == 0 ) {
return '[[' . $LT5000_call_out . '|]]';
} else {
return '[[' . $LT5000_call_out . '|' . $matches[0] . ']]';
}
}
static function CallBackCaseSensitive($matches) {
if ($LT5000_pos !== false){
# this if a / was found in the first place
$LT5000_call_out = $LT_namespacePart . $LT5000_front . '/' . $LT5000_back;
} else {
# this if there was no slash
$LT5000_call_out = $LT_namespacePart . $matches[0];
}
if ( strcmp(substr(LinkTitles_5000::$safeTitle, 0), substr($matches[0], 0)) == 0 ) {
return '[['. $LT5000_call_out . '|]]';
} else {
return '[[' . $LT5000_call_out . '|' . $matches[0] . ']]';
}
}
static function removeMagicWord( &$parser, &$text ) {
$mw = MagicWord::get('MAG_LINKTITLES_TERMINOLOGY_NOAUTOLINKS');
$mw -> matchAndRemove( $text );
return true;
}
}
And the modules loader function LinkTitles_5000.php:
if ( !defined( 'MEDIAWIKI' ) ) {
die( 'Not an entry point.' );
}
/*
error_reporting(E_ALL);
ini_set('display_errors', 'On');
ini_set('error_log', 'php://stderr');
$wgMainCacheType = CACHE_NONE;
$wgCacheDirectory = false;
*/
// Configuration variables
$wgLinkTitlesPreferShortTitles = false;
$wgLinkTitlesMinimumTitleLength = 3;
$wgLinkTitlesParseHeadings = false;
$wgLinkTitlesParseOnEdit = true;
$wgLinkTitlesParseOnRender = false;
$wgLinkTitlesSkipTemplates = false;
$wgLinkTitlesBlackList = array();
$wgLinkTitlesFirstOnly = false;
$wgLinkTitlesWordStartOnly = true;
$wgLinkTitlesWordEndOnly = true;
$wgLinkTitlesSmartMode = true;
$wgLinkTitlesNamespaceWhitelist = array();
$wgExtensionCredits['parserhook'][] = array(
'path' => FILE,
'name' => 'LinkTitles_5000',
'author' => '[https://www.mediawiki.org/wiki/User:Bovender Daniel Kraus]',
'url' => 'https://www.mediawiki.org/wiki/Extension:LinkTitles',
'version' => '2.2.0',
'descriptionmsg' => 'linktitles-desc'
);
$wgExtensionMessagesFiles['LinkTitles_5000'] = dirname( FILE ) . '/LinkTitles_5000.i18n.php';
$wgExtensionMessagesFiles['LinkTitlesMagic_5000'] = dirname( FILE ) . '/LinkTitles_5000.i18n.magic.php';
$wgAutoloadClasses['LinkTitles_5000'] = dirname( FILE ) . '/LinkTitles_5000.body.php';
$wgExtensionFunctions[] = 'LinkTitles_5000::setup';
// vim: ts=2:sw=2:noet

Forgot about this question from a long time ago, but it turns out MediaWiki has a buit in function for this
$myNamespace = $article->getTitle()->getNamespace();
Since the article object is by default passed to an extension hooked to an on_save process, this will get the namespace as a numeric value.

Related

Not able to remove backslash from below code?

below is my code the issue is that when i enter any username with apostrophe (') Additional character "\ backslash" is being displayed when Search results are returned.
Below is my code i find that a function addslashes is used in the checkusername function so backslash is getting added.
if ( 0 < count( $my_field_place ))
{
for ( $i = 0; $i < count( $my_field_place ); $i++ )
{
if ( true === isset( $Fields[$i] ))
{
print "gMapping[$i] = new MappingItem( '" .
addslashes( $Fields[$i] ) .
"', '" .
checkusername( $my_field_place[$i] ) .
"' );";
}
}
}
function checkusername($inStr)
{
$orig = array();
$new = array();
$orig[00] = "/\n/`" ; $new[00] = "\\?n";
$orig[01] = "/[^\x-*()]/"; $new[01] = "";
$var1 = preg_replace($orig, $new, $inStr);
$var2 = addslashes($var1 ); // i am not sure why addslashes is used but i am asked not to remove because of security reasion?
return $var2;
}
Note: I google and find that it used for security reason
Since in my case we are only displaying the searched result. So i am not sure why this function is used here.
My fix is to add stripslashes() function before returning which will removes backslashes added by the addslashes() function.
Please find the code snippet and the comment for code change below:
function checkusername($inStr)
{
$orig = array();
$new = array();
$orig[00] = "/\n/`" ; $new[00] = "\\?n";
$orig[01] = "/[^\x-*()]/"; $new[01] = "";
$var1 = preg_replace($orig, $new, $inStr);
$var2 = addslashes($var1);
return stripslashes($var2); // i am not sure stripslashes is correct fix or not?
}
Please help is it fine to added stripslashes or is there any other way to handle it ?
You can restrict user from those special characeter
though in gmail ,yahoo,fb etc they will never
allow this character.since t allows multiple words to be represented in a somewhat readable manner
below are some doc
https://support.google.com/a/answer/33386?hl=en
see second guidelines

Count the number of times a WordPress shortcode is used in a post

I have the following WordPress shortcode function:
function wp_shortcode() {
static $i=1;
$return = '['.$i.']';
$i++;
return $return;
}
add_shortcode('shortcode', 'wp_shortcode');
This works fine. The $i variable gets incremented each time the function is called in the article. So for
[shortcode][shortcode][shortcode][shortcode]
the output is as expected
[1][2][3][4]
but
if the article has more than one page, than the counter resets on the next article page. So for:
[shortcode][shortcode][shortcode][shortcode]
<!--nextpage-->
[shortcode][shortcode][shortcode][shortcode]
the output is
[1][2][3][4]
<!--nextpage-->
[1][2][3][4]
instead of the wanted output of:
[1][2][3][4]
<!--nextpage-->
[5][6][7][8]
Anyway to change this?
So after researching a bit more #diggy's idea with pre processing the_content and adding the $atts to the shorcodes before the shortcodes are rendered, I came up with this:
function my_shortcode_content( $content ) {
//check to see if the post has your shortcode, skip do nothing if not found
if( has_shortcode( $content, 'shortcode' ) ):
//replace any shortcodes to the basic form ([shortcode 1] back to [shortcode])
//usefull when the post is edited and more shortcodes are added
$content = preg_replace('/shortcode .]/', 'shortcode]', $content);
//loop the content and replace the basic shortcodes with the incremented value
$content = preg_replace_callback('/shortocode]/', 'rep_count', $content);
endif;
return $content;
}
add_filter( 'content_save_pre' , 'my_shortcode_content' , 10, 1);
function rep_count($matches) {
static $i = 1;
return 'shortcode ' . $i++ .']';
}
Nice question. A possible solution below, however not exactly elegant because it requires you to have a fixed number of shortcodes on each page, e.g. 4:
add_shortcode( 'shortcode', 'wp_shortcode' );
function wp_shortcode() {
global $page;
$spp = 4;
static $i = 1;
$ii = $i + ( ( $page - 1 ) * $spp );
$return = '['.$ii.']';
$i++;
return $return;
}
If you need to just count the total tags in a page/post you can use this:
function count_shortcodes( $content, $tag ) {
if ( false === strpos( $content, '[' ) ) {
return 0;
}
if ( shortcode_exists( $tag ) ) {
preg_match_all( '/' . get_shortcode_regex() . '/', $content, $matches, PREG_SET_ORDER );
if ( empty( $matches ) )
return 0;
$count = 0;
foreach ( $matches as $shortcode ) {
if ( $tag === $shortcode[2] ) {
$count++;
} elseif ( ! empty( $shortcode[5] ) && has_shortcode( $shortcode[5], $tag ) ) {
$count++;
}
}
return $count;
}
return 0;
}
It is happens, because on every page load you redefined your function, so static $i=1; will executed always.
Maybe you want to use a $_SESSION variable. But do not forget the session_start() somewhere in init callback.
function wp_shortcode() {
if (empty($_SESSION["myCounter"])) {
$_SESSION["myCounter"] = 1;
}
$return = '<a href="#f' . $_SESSION["myCounter"] . '" name="r'
. $_SESSION["myCounter"] . '">['
. $_SESSION["myCounter"] . ']</a>';
$_SESSION["myCounter"]++;
return $return;
}
add_shortcode('shortcode', 'wp_shortcode');
Setting the session, put it into the functions.php
add_action('init', 'my_init');
function my_init() {
if (!session_id()) {
session_start();
}
//Other init here
}

turning this trainwreck of a function into a recursive one

I've been trying to build this recursive function for the better part of a day now, but I just can't seem to get it to work the way I want.
First, I have a property which holds some data that the function have to access:
$this->data
And then I have this string which the intention is to turn into a relative path:
$path = 'path.to.%id%-%folder%.containing.%info%';
The part of the string that are like this: %value% will load some dynamic values found in the $this->data property (like so: $this->data['id']; or $this->data['folder'];
and to make things really interesting, the property can reference itself again like so: $this->data['folder'] = 'foldername.%subfolder%'; and also have two %values% separated by a - that would have to be left alone.
So to the problem, I've been trying to make a recursive function that will load the dynamic values from the data property, and then again if the new value contains another %value% and so on until no more %value%'s are loaded.
So far, this is what I've been able to come up with:
public function recursiveFolder( $folder, $pathArr = null )
{
$newPathArr = explode( '.', $folder );
if ( count ( $newPathArr ) !== 1 )
{
foreach( $newPathArr as $id => $folder )
{
$value = $this->recursiveFolder( $folder, $newPathArr );
$resultArr = explode( '.', $value );
if ( count ( $resultArr ) !== 1 )
{
foreach ( $resultArr as $nid => $result )
{
$nvalue = $this->recursiveFolder( $result, $newPathArr );
$resultArr[$nid] = $nvalue;
}
}
$resultArr = implode( '.',$resultArr );
$newPathArr[$id] = $resultArr;
}
}
else
{
$pattern = '/%(.*?)%/si';
preg_match_all( $pattern, $folder, $matches );
if ( empty( $matches[0] ) )
{
return $folder;
}
foreach ( $matches[1] as $mid => $match )
{
if ( isset( $this->data[$match] ) && $this->data[$match] != '' )
{
$folder = str_replace( $matches[0][$mid], $this->data[$match], $folder );
return $folder;
}
}
}
return $newPathArr;
}
Unfortunately it is not a recursive function at all as it grinds to a halt when it has multiple layers of %values%, but works with two layers -barely-. (I just coded it so that it would work at a bare minimalistic level this point).
Here's how it should work:
It should turn:
'files.%folder%.blog-%type%.and.%time%'
into:
'files.foldername.blog-post.and.2013.feb-12th.09'
based on this:
$data['folder'] = 'foldername';
$data['type'] = 'post';
$data['time'] = '%year%.%month%-%day%';
$data['year'] = 2013;
$data['month'] = 'feb';
$data['day'] = '12th.%hour%';
$data['hour'] = '09';
Hope you can help!
Jay
I don't see the need for this too be solved recursively:
<?php
function putData($str, $data)
{
// Repeat the replacing process until no more matches are found:
while (preg_match("/%(.*?)%/si", $str, $matches))
{
// Use $matches to make your replaces
}
return $str;
}
?>

php - usage nested loops and case

First of all - excuse me if my rudimentary PHP skills has pushed me into asking something which might be basic or trivial, but I have searched the site without results (maybe because i do not know the technical term for such a thing ..)
I have a nested for each loop , but based on simple variables ($e) , I would need to either use the whole loop (2 nested parts) OR use only one (the inner).
$a = array(); //some array ...
$c = array(); //some other array ...
$e = 'yes' // or 'no'
if ($a) {
foreach ($a as $b) {
$a_1[] = 'something_quite_long'; //that would affects $c if used
foreach ( $c as $d ) {
//do_something_very long...
}
}
}
so right now I have resolved this by using switch $e: and case - but that has moer than duplicated the length of my code , because what I did was made one case as the whole nested loop, and the other case - the only inner loop (which is loooong..)
I am sure there is some ninja-technique to use in such a case without simply copying and pasting the whole code in a "case" - but I have no idea how .
Anyone ?
NOTE : I know I could presumably use an external function, but the problem is that in the very long second (inner) loop - there are one or two minor cases where the verbal output (HTML) would change slightly ..
Edit I - Due to unclarity from comments , here is the code (with much reduced loops - the actual loop is much longer) - although not relevant to the question. the code is wordpress related..
function o99_get_image_size_links($title='',$single,$recieved_id) {
/* If not viewing an image attachment page, return. */
/* Set up an empty array for the links. */
$links = array();
/* Get the intermediate image sizes and add the full size to the array. */
$sizes = get_intermediate_image_sizes();
$sizes[] = 'full';
global $post;
switch ($single) {
case 'FALSE':
// this will do to all images attached to a post ..
$attachments = get_children( array('post_parent' => $post->ID, 'post_status' => 'inherit', 'post_type' => 'attachment','post_mime_type' => $mime, 'order' => 'ASC', 'orderby' => 'menu_order ID', 'posts_per_page'=>$limit) );
/* Loop through each of the image sizes. */
if ($attachments) {
foreach ($attachments as $att) {
$links[] = '<br>' . get_the_title($att->ID) .' || '. basename ( get_attached_file( $att->ID ) ).' || '. $att->post_name .' || ' /*. wp_get_attachment_image( $att->ID, 'tooltip' ).' || ' .'<br/>'*/ ; // k99 add
if ($title) {
$links[] = '<br><b>' . $title . '</b></br>';
}
foreach ( $sizes as $size ) {
/* Get the image source, width, height, and whether it's intermediate. */
$image = wp_get_attachment_image_src( $att->ID, $size );
/* Add the link to the array if there's an image and if $is_intermediate (4th array value) is true or full size. */
if ( !empty( $image ) && ( true == $image[3] || 'full' == $size ) )
$links[] = "</br><a class='image-size-link_{$image[1]}×{$image[2]}' href='{$image[0]}'>{$image[1]} × {$image[2]}</a>";
}
}
}
break;
//case for single image ..
case 'TRUE':
$links[] = '<br>' . get_the_title($recieved_id) .' || '. basename ( get_attached_file( $recieved_id ) ).' || '. $att->post_name .' || ' /*. wp_get_attachment_image( $att->ID, 'tooltip' ).' || ' .'<br/>'*/ ; // k99 add
if ($title) {
$links[] = '<br><b>' . $title . '</b></br>';
}
foreach ( $sizes as $size ) {
/* Get the image source, width, height, and whether it's intermediate. */
$image = wp_get_attachment_image_src( $recieved_id, $size );
/* Add the link to the array if there's an image and if $is_intermediate (4th array value) is true or full size. */
if ( !empty( $image ) && ( true == $image[3] || 'full' == $size ) )
$links[] = "</br><a class='image-size-link_{$image[1]}×{$image[2]}' href='{$image[0]}'>{$image[1]} × {$image[2]}</a>";
}
break;
}
/* Join the links in a string and return. */
return join( '<span class="sep"> /</span> ', $links );
}
I have so many issues with your code .. but this is to give you an idea how to minimized your code
Issues
Use Of global global $post;
$mime and $limit not declared
basename ( get_attached_file( $recieved_id ) ).' || '. $att->post_name .' || ' outside the loop that defines foreach ($attachments as $att)
$recieved_id var argument and $post->ID via post ????
etc
There is no way your script can work with this error .. so i'll just give you a guide on how to improve your function
function k99_get_image_size_links($title = '', $single , $recieved_id , $mime =null , $limit = null) {
$links = array();
$sizes = get_intermediate_image_sizes();
$sizes[] = 'full';
$pad = function ($ID) use(&$links,$sizes,$title) {
$links[] = '<br>' . get_the_title($ID) . ' || ' . basename(get_attached_file($ID)) . ' || ' . $title . ' || ' ;
empty($title) OR $links[] = sprintf('<br><b>%s</b></br>',$title);
foreach ( $sizes as $size ) {
$image = wp_get_attachment_image_src($ID, $size);
if (! empty($image) && (true == $image[3] || 'full' == $size))
$links[] = sprintf('</br><a class="image-size-link_%s×%s" href="%s">%1$s × %2$s</a>',$image[1],$image[2],$image[0]);
}
};
if ($single === true) {
$pad($recieved_id);
} else {
$attachments = get_children(array('post_parent' => $recieved_id,'post_status' => 'inherit','post_type' => 'attachment',
'post_mime_type' => $mime,'order' => 'ASC','orderby' => 'menu_order ID','posts_per_page' => $limit));
if ($attachments) {
foreach ( $attachments as $att ) {
$pad($att->ID);
}
}
}
return join('<span class="sep"> /</span> ', $links);
}
Please Not the above code is not tested just to show you how you can use Closure remove duplication in your code
Some notes:
if ($a) {
foreach ($a as $b) {
As $a is an array and only an array evaluates true in the if, you don't need the if at all. foreach will do zero iterations on an empty array, so the if is superfluous.
$d = 'yes' // or 'no'
...
foreach ( $c as $d ) {
^^^
You are overwriting the $d variable here. That might cause your problem. Let's clean the code an review:
$a = array(); //some array ...
$c = array(); //some other array ...
$e = 'yes' // or 'no'
foreach ($a as $b)
{
$a_1[] = 'something_quite_long'; //that would affects $c if used
foreach ($c as $d)
{
// do_something_very long...
}
}
If you now give the variables better names, the looping should have become more clear so less places to do errors.
You can break out of a foreach loop with the break; command which skips out of the loop and carries on with the next step which in your code is the next iteration of the outer loop. Also you are overwriting $d in each iteration of the inner loop here foreach ($c as $d)

Retrieve the country code in PHP

I'm a little lost with that.
How can I retrieve the ISO country code of the visitors at one php page?
Thanks advance
You can either do this by Geolocation of the IP or by inspecting the right headers.
Usually you want the latter, since it tells you which languages the browser/system uses. You will only want to use geolocation when you want to know the physical location.
The header is stored in $_SERVER['HTTP_ACCEPT_LANGUAGE']. It contains comma-separated entries, e.g.: en-GB,en;q=0.8,en-US;q=0.6,nl;q=0.4 (my own)
The HTTP Accept Language parameters seperates it's languages by a comma, it's properties by a semicolon. The q-value is from 0 to 1, with 1 being the highest/most preferred. Here is some naive and untested code to parse it:
$langs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
$preffered = "";
$prefvalue = 0;
foreach($langs as $lang){
$info = explode(';', $lang);
$val = (isset($lang[1])?$lang[1];1);
if($prefvalue < $val){
$preferred = $lang[0];
$prefvalue = $val;
}
}
Much simpler is it if you want to test if a specific language is accepted, e.g. Spanish (es):
if(strpos($_SERVER['HTTP_ACCEPT_LANGUAGE'], "es") !== false){
// Spanish is supported
}
I think you could use this php script which uses an ip and prints out a country code
Example
http://api.hostip.info/country.php?ip=4.2.2.2
Gives US
Check out
http://www.hostip.info/use.html
for more info.
A library i use myself and can recommend, is MaxMind GeoLite Country. To get the country code, you need only to copy 2 files to your server, the php code geoip.inc and the binary data GeoIP.dat.
Using the library is also very straightforward:
function ipToCountry()
{
include_once('geoip/geoip.inc');
$gi = geoip_open(__DIR__ . '/geoip/GeoIP.dat', GEOIP_STANDARD);
$result = geoip_country_code_by_addr($gi, $_SERVER['REMOTE_ADDR']);
geoip_close($gi);
return $result;
}
This will use GeoIp and fall back to accept_lang
class Ip2Country
{
function get( $target )
{
$country = false;
if( function_exists( 'geoip_record_by_name' ) )
$country = $this->getFromIp( $target );
if( !$country && isset( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) )
$country = $this->getFromLang( $_SERVER['HTTP_ACCEPT_LANGUAGE'] );
return $country;
}
function getFromIp( $target )
{
$dat = #geoip_record_by_name( $target );
return ( isset( $dat['country_code'] ) ) ? mb_strtolower( $dat['country_code'] ) : false;
}
function getFromLang( $str )
{
$info = array();
$langs = explode( ',', $str );
foreach( $langs as $lang )
{
$i = explode( ';', $lang );
$j = array();
if( !isset( $i[0] ) ) continue;
$j['code'] = $i[0];
if( strstr( $j['code'], '-' ) )
{
$parts = explode( '-', $j['code'] );
$j['lang'] = $parts[0];
$j['country'] = mb_strtolower( $parts[1] );
}
$info[] = $j;
}
return ( isset( $info[0]['country'] ) ) ? $info[0]['country'] : false;
}
}
$x = new Ip2Country();
var_dump( $x->get( 'canada.ca' ) );

Categories