php - usage nested loops and case - php

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)

Related

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;
}
?>

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

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.

Php regex returning repeats in nested arrays

I'm trying to get a list of all occurrences of a file being included in a php script.
I'm reading in the entire file, which contains this:
<?php
echo 'Hello there';
include 'some_functions.php';
echo 'Trying to find some includes.';
include 'include_me.php';
echo 'Testtest.';
?>
Then, I run this code on that file:
if (preg_match_all ("/(include.*?;){1}/is", $this->file_contents, $matches))
{
print_r($matches);
}
When I run this match, I get the expected results... which are the two include sections, but I also get repeats of the exact same thing, or random chunks of the include statement. Here is an example of the output:
Array (
[0] => Array ( [0] => include 'some_functions.php'; [1] => include 'include_me.php'; )
[1] => Array ( [0] => include 'some_functions.php'; [1] => include 'include_me.php'; ) )
As you can see, it's nesting arrays with the same result multiple times. I need 1 item in the array for each include statement, no repeats, no nested arrays.
I'm having some trouble with these regular expressions, so some guidance would be nice. Thank you for your time.
what about this one
<?php
preg_match_all( "/include(_once)?\s*\(?\s*(\"|')(.*?)\.php(\"|')\s*\)?\s*;?/i", $this->file_contents, $matches );
// for file names
print_r( $matches[3] );
// for full lines
print_r( $matches[0] );
?>
if you want a better and clean way, then the only way is php's token_get_all
<?php
$tokens = token_get_all( $this->file_contents );
$files = array();
$index = 0;
$found = false;
foreach( $tokens as $token ) {
// in php 5.2+ Line numbers are returned in element 2
$token = ( is_string( $token ) ) ? array( -1, $token, 0 ) : $token;
switch( $token[0] ) {
case T_INCLUDE:
case T_INCLUDE_ONCE:
case T_REQUIRE:
case T_REQUIRE_ONCE:
$found = true;
if ( isset( $token[2] ) ) {
$index = $token[2];
}
$files[$index] = null;
break;
case T_COMMENT:
case T_DOC_COMMENT:
case T_WHITESPACE:
break;
default:
if ( $found && $token[1] === ";" ) {
$found = false;
if ( !isset( $token[2] ) ) {
$index++;
}
}
if ( $found ) {
if ( in_array( $token[1], array( "(", ")" ) ) ) {
continue;
}
if ( $found ) {
$files[$index] .= $token[1];
}
}
break;
}
}
// if your php version is above 5.2
// $files index will be line numbers
print_r( $files );
?>
Use get_included_files(), or the built-in tokenizer if the script is not included
I'm searching through a string of another files contents and not the
current file
Then your best bet is the tokenizer. Try this:
$scriptPath = '/full/path/to/your/script.php';
$tokens = token_get_all(file_get_contents($scriptPath));
$matches = array();
$incMode = null;
foreach($tokens as $token){
// ";" should end include stm.
if($incMode && ($token === ';')){
$matches[] = $incMode;
$incMode = array();
}
// keep track of the code if inside include statement
if($incMode){
$incMode[1] .= is_array($token) ? $token[1] : $token;
continue;
}
if(!is_array($token))
continue;
// start of include stm.
if(in_array($token[0], array(T_INCLUDE, T_INCLUDE_ONCE, T_REQUIRE, T_REQUIRE_ONCE)))
$incMode = array(token_name($token[0]), '');
}
print_r($matches); // array(token name, code)
Please read, how works preg_match_all
First item in array - it return all text, which is in regular expression.
Next items in array - that's texts from regular expression (in parenthesises).
You should use $matches[1]

Better way to check for URL in PHP

Is there a better way or elegance to do this? I've been using this code to check the similar url in database base on the pattern provide.
$menu_selected = '';
$uri_array = explode('/','commodity/statement/flour/factory/');
$menus = array(
'commodity/search/flour/factory/index',
'commodity/statement/sugar/branch/index'
);
$pattern_parts = explode('/', '=/*/=/=/*');
foreach ($menus as $menu) {
$url_parts = explode('/',$menu);
if( count($pattern_parts) == count($url_parts) ){
#[i] Trim down for wildcard pattern
foreach($pattern_parts as $i => $part ){
if( $part == '*' ) {
unset($pattern_parts[$i]);
unset($url_parts[$i]);
unset($uri_array[$i]);
}
}
#[i] Join array and compare
if( join('/', $uri_array) == join('/', $url_parts) ) {
// Found and return the selected
$menu_selected = $menu;
break;
}
}
}

Categories