Strpos offset in PHP not working as expected? - php

I've been pulling my hair for hours for this. I'm trying to find all the positions of iframe The first occurrence is successful but not the second one.
Here's my code
$ofAllIFrames = qp( $this->content, 'iframe' );
$iframes = array();
$allIframes = array();
$startTag = 0;
foreach( $ofAllIFrames as $iframe) {
$startCurrentTag = strpos( $this->content, '<iframe>', $startTag );
$endCurrentTag = strpos( $this->content, '</iframe>', $startTag );
$iframes[] = array(
'start' => $startCurrentTag,
'end' => $endCurrentTag
);
$allIframes[] = $iframe;
$startTag = $endCurrentTag;
var_dump($startTag);
ob_flush();
}
return array(
'hasIFrame' => count( $allIframes ) > 0,
'elements' => $iframes
);
And this is my test case
public function test_if_content_has_multiple_iframes() {
$content = 'some content <iframe></iframe> <iframe id="1"></iframe> and another content';
$iframeChecker = new IFrame_Checker( $content );
$params = $iframeChecker->check();
$this->assertTrue( $params['hasIFrame'] );
$this->assertEquals( 13, $params['elements'][0]['start'] );
$this->assertEquals( 21, $params['elements'][0]['end'] );
$this->assertEquals( 31, $params['elements'][1]['start'] );
$this->assertEquals( 46, $params['elements'][1]['end'] );
}
And the test failed for the second iframe
1) Test_IFrame::test_if_content_has_multiple_iframes
Failed asserting that false matches expected 31.

$startCurrentTag = strpos( $this->content, '<iframe>', $startTag );
$endCurrentTag = strpos( $this->content, '</iframe>', $startCurrentTag );
Should work better.
Reason:
$startTag equals $endCurrentTag from the previous loop which refers to the offset at </iframe>.... So this is going to return the same position if you use $endCurrentTag = strpos( $this->content, '</iframe>', $startTag );

Related

How add font php

I have such a small request because I have a php code and I do not know how to add a font to it, I know I have to add an imageloadfont but when it adds the generator just does not work. I've tried everything in my mind and nothing at all.
<?php
if( isSet( $_GET[ 'Address' ] ) )
{
$szAddress = $_GET[ 'Address' ];
$szExploded = explode( ":", $szAddress );
$szServerIP = $szExploded[ 0 ];
$szServerPort = $szExploded[ 1 ];
$Query = new SourceQuery( );
$Info = Array( );
$Rules = Array( );
$Players = Array( );
try
{
$Query -> Connect( $szServerIP, $szServerPort, DEF__TIME_OUT);
$Info = $Query -> GetInfo( );
$Players = $Query -> GetPlayers( );
$Rules = $Query -> GetRules( );
}
catch( Exception $e )
{
$Exception = $e;
}
$Query -> Disconnect( );
header( "Content-type: image/png" );
$rImage = imagecreatefrompng( DEF__IMAGE_NAME );
$iColor = imagecolorallocate( $rImage, DEF__COLOR_RED, DEF__COLOR_GREEN, DEF__COLOR_BLUE );
// bool imagestring ( resource $image , int $font , int $x , int $y , string $string , int $color )
imagestring( $rImage, DEF__ADDRESS_TEXT_SIZE, DEF__ADDRESS_X, DEF__ADDRESS_Y, $szAddress, $iColor );
if( $Info[ 'MaxPlayers' ] != 0 )
{
$szHostName = MIRAGE;
$szMapName = $Info[ 'Map' ];
if( strlen( $szHostName ) > DEF__HOSTNAME_MAX_TEXT_LEN )
{
$szHostName = substr( $Info[ 'HostName' ], 0, DEF__HOSTNAME_MAX_TEXT_LEN ). ' ...';
}
if( strlen( $szMapName ) > DEF__MAP_MAX_TEXT_LEN )
{
$szMapName = substr( $szMapName, 0, DEF__MAP_MAX_TEXT_LEN ). '..';
}
imagestring( $rImage, DEF__HOSTNAME_TEXT_SIZE, DEF__HOSTNAME_X, DEF__HOSTNAME_Y, $szHostName, $iColor );
imagestring( $rImage, DEF__MAP_TEXT_SIZE, DEF__MAP_X, DEF__MAP_Y, $szMapName, $iColor );
imagestring( $rImage, DEF__PLAYERS_TEXT_SIZE, DEF__PLAYERS_X, DEF__PLAYERS_Y, $Info[ 'Players' ]. '/' .$Info[ 'MaxPlayers' ], $iColor );
}
else
{
imagestring( $rImage, DEF__PLAYERS_TEXT_SIZE, DEF__PLAYERS_X, DEF__PLAYERS_Y, "SERVER OFF", $iColor );
}
$font_width = ImageFontWidth(5);
imagepng( $rImage );
imagedestroy( $rImage );
}
?>

Replacing text within string that contains serialize arrays

Thanks for clicking on the question. I am trying to find and replace text within a string that contains serialize arrays. For example :
'fgm2wc_options', 'a:19:{s:15:"automatic_empty";N;s:3:"url";s:25:"http://example.com/store/";s:8:"hostname";s:9:"localhost";s:4:"port";s:4:"3306";s:8:"database";s:22:"apgadmin_store_magento";s:8:"username" ... }
I want to change http://example.com/ to smth else I can do it with str_replace but it will not change the string length indicator ( e.g s:25 ).
This is a function i am using:
function recursive_unserialize_replace( $old_url = '', $new_url = '', $data = '', $serialised = false ) {
$new_url = rtrim( $new_url, '/' );
$data = explode( ', ', $data );
try {
if ( is_string( $data ) && ( $unserialized = #unserialize( $data ) ) !== false ) {
$data = recursive_unserialize_replace( $old_url, $new_url, $unserialized, true );
} elseif ( is_array( $data ) ) {
$_tmp = array( );
foreach ( $data as $key => $value ) {
$_tmp[ $key ] = recursive_unserialize_replace( $old_url, $new_url, $value );
}
$data = $_tmp;
unset( $_tmp );
} else {
if ( is_string( $data ) ) {
$data = str_replace( $old_url, $new_url, $data );
}
}
if ( $serialised ) {
return serialize( $data );
}
} catch( Exception $error ) {
}
return $data;
}
Any ideas ?
For anyone interested this is the solution i came up with:
function unserialize_replace( $old_url = '', $new_url = '', $database_string = '' ) {
if ( substr( $old_url, -1 ) !== '/' ) {
$new_url = rtrim( $new_url, '/' );
}
$serialized_arrays = preg_match_all( "/a:\d+:.*\;\}+/", $database_string, $matches );
if( !empty( $serialized_arrays ) && is_array( $matches ) ) {
foreach ( $matches[ 0 ] as $match ) {
$unserialized = #unserialize( $match );
if ( $unserialized ) {
$buffer = str_replace( $old_url, $new_url, $unserialized );
$buffer = serialize( $buffer );
$database_string = str_replace( $match, $buffer, $database_string );
}
}
}
if ( is_string( $database_string ) ) {
$database_string = str_replace( $old_url, $new_url, $database_string );
}
return $database_string;
}
Thanks for the suggestions. Please let me know if you see anything wrong and anything i can improve

Warning: date() expects parameter 2 to be long,

Getting the followoing error:
Warning: date() expects parameter 2 to be long, string given in
/home/users/2/catfood.jp-cybercat/web/academy/wp-includes/functions.php
on line 112
Which points to the line:
$datemonth = $wp_locale->get_month( $datefunc( 'm', $i ) );
What changes are required to the above line to resolve this?
Here is the whole codes
function date_i18n( $dateformatstring, $unixtimestamp = false, $gmt = false ) {
global $wp_locale;
$i = $unixtimestamp;
if ( false === $i ) {
if ( ! $gmt )
$i = current_time( 'timestamp' );
else
$i = time();
// we should not let date() interfere with our
// specially computed timestamp
$gmt = true;
}
/*
* Store original value for language with untypical grammars.
* See https://core.trac.wordpress.org/ticket/9396
*/
$req_format = $dateformatstring;
$datefunc = $gmt? 'gmdate' : 'date';
if ( ( !empty( $wp_locale->month ) ) && ( !empty( $wp_locale->weekday ) ) ) {
$datemonth = $wp_locale->get_month( $datefunc( 'm', $i ) );
$datemonth_abbrev = $wp_locale->get_month_abbrev( $datemonth );
$dateweekday = $wp_locale->get_weekday( $datefunc( 'w', $i ) );
$dateweekday_abbrev = $wp_locale->get_weekday_abbrev( $dateweekday );
$datemeridiem = $wp_locale->get_meridiem( $datefunc( 'a', $i ) );
$datemeridiem_capital = $wp_locale->get_meridiem( $datefunc( 'A', $i ) );
$dateformatstring = ' '.$dateformatstring;
$dateformatstring = preg_replace( "/([^\\\])D/", "\\1" . backslashit( $dateweekday_abbrev ), $dateformatstring );
$dateformatstring = preg_replace( "/([^\\\])F/", "\\1" . backslashit( $datemonth ), $dateformatstring );
$dateformatstring = preg_replace( "/([^\\\])l/", "\\1" . backslashit( $dateweekday ), $dateformatstring );
$dateformatstring = preg_replace( "/([^\\\])M/", "\\1" . backslashit( $datemonth_abbrev ), $dateformatstring );
$dateformatstring = preg_replace( "/([^\\\])a/", "\\1" . backslashit( $datemeridiem ), $dateformatstring );
$dateformatstring = preg_replace( "/([^\\\])A/", "\\1" . backslashit( $datemeridiem_capital ), $dateformatstring );
$dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) -1 );
}
$timezone_formats = array( 'P', 'I', 'O', 'T', 'Z', 'e' );
$timezone_formats_re = implode( '|', $timezone_formats );
if ( preg_match( "/$timezone_formats_re/", $dateformatstring ) ) {
$timezone_string = get_option( 'timezone_string' );
if ( $timezone_string ) {
$timezone_object = timezone_open( $timezone_string );
$date_object = date_create( null, $timezone_object );
foreach( $timezone_formats as $timezone_format ) {
if ( false !== strpos( $dateformatstring, $timezone_format ) ) {
$formatted = date_format( $date_object, $timezone_format );
$dateformatstring = ' '.$dateformatstring;
$dateformatstring = preg_replace( "/([^\\\])$timezone_format/", "\\1" . backslashit( $formatted ), $dateformatstring );
$dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) -1 );
}
}
}
}
$j = #$datefunc( $dateformatstring, $i );
/**
* Filter the date formatted based on the locale.
*
* #since 2.8.0
*
* #param string $j Formatted date string.
* #param string $req_format Format to display the date.
* #param int $i Unix timestamp.
* #param bool $gmt Whether to convert to GMT for time. Default false.
*/
$j = apply_filters( 'date_i18n', $j, $req_format, $i, $gmt );
return $j;
}
$datefunc is an alias obviously to php's date method. If that's the case, you are trying to get the month from passing a single integer 1-12. When you can't do that, you need to pass a timestamp to PHP's date method then depending on the attributes you pass as options will return you the following data. Then you are passing it to wordpress locale get_month method that returns the name of the month. You need to refactor your code, so that $i isn't a for loop variable. If you are just trying to get Jan - Dec just do
$i = 1;
$monthArray = [];
do {
// Just push the months to an array and pass it to the view
array_push($monthArray, $wp_locale->get_month($i);
$i++;
} while($i < 13);
Then do what you need to with it. If you are getting a record back from the DB, you need to access the appropriate value in the returned model. Otherwise you're passing an array object. If you are accessing a model you should do)
// Access the property that you intended to retrieve the month on.
$datemonth = $wp_locale->get_month( $datefunc( 'm', $i['published_at'] ) );
I added a plugin called "paid membership pro" and this plugin was written in English and I translated into Japanese. There were lots of codes like this:
<?php printf(__('課金 #%s ( %s )', 'pmpro'), $pmpro_invoice->code, date_i18n(get_option('date_format'), $pmpro_invoice->timestamp));?>
I tried to change these codes as follows:
timestamp), $pmpro_invoice->code );?>
I guess that's why it caused the problem. What do you think?
Now I downloaded the plugin again and there is no problem.
Thank you for helping me.

Remove from Array if Contains Lowercase Letter

I have a number of WordPress posts that will each have two tags, one tag is the State and the other tag is an Airport Code.
I'm able to generate a dropdown menu from the tags using the instructions here: http://www.wprecipes.com/wordpress-hack-display-your-tags-in-a-dropdown-menu
But, I would like to actually have two different dropdowns, one that lists the States in alpha order, the other lists the Airports in alpha order. Every Airport will always be three uppercase letters. Is there an argument that I can add to to this so that I can create one dropdown for Airports and another for States?
If it contains a lowercase letter, it goes in the State dropdown. If no lowercase, it's an airport.
I modify the snippet from your attached tutorials into something like this:
function dropdown_tag_cloud( $args = '' ) {//supported: 'all', 'airport', 'state'
$defaults = array(
'smallest' => 8, 'largest' => 22, 'unit' => 'pt', 'number' => 45,
'format' => 'flat', 'orderby' => 'name', 'order' => 'ASC',
'exclude' => '', 'include' => '', 'tags_mode' => 'all'
);
$args = wp_parse_args( $args, $defaults );
print_r($args);
$tags = get_tags( array_merge($args, array('orderby' => 'count', 'order' => 'DESC')) ); // Always query top tags
if ( empty($tags) )
return;
$return = dropdown_generate_tag_cloud( $tags, $args ); // Here's where those top tags get sorted according to $args
if ( is_wp_error( $return ) ){
echo "wp error...";
return false;
}else
echo apply_filters( 'dropdown_tag_cloud', $return, $args );
}
function dropdown_generate_tag_cloud( $tags, $args = '' ) {
global $wp_rewrite;
$defaults = array(
'smallest' => 8, 'largest' => 22, 'unit' => 'pt', 'number' => 45,
'format' => 'flat', 'orderby' => 'name', 'order' => 'ASC'
);
$args = wp_parse_args( $args, $defaults );
extract($args);
if ( !$tags )
return;
$counts = $tag_links = array();
foreach ( (array) $tags as $tag ) {
if($tags_mode == 'airport'){
//if uppercased tag is equal to the tag
//which means current tag already uppercased.
if(!(strtoupper($tag->name) == $tag->name))
continue;//skip current tag
} else if($tags_mode == 'state'){
//if uppercased tag is equal to the tag
//which means current tag already uppercased.
if((strtoupper($tag->name) == $tag->name))
continue;//skip current tag
}
$counts[$tag->name] = $tag->count;
$tag_links[$tag->name] = get_tag_link( $tag->term_id );
if ( is_wp_error( $tag_links[$tag->name] ) )
return $tag_links[$tag->name];
$tag_ids[$tag->name] = $tag->term_id;
}
$min_count = min($counts);
$spread = max($counts) - $min_count;
if ( $spread <= 0 )
$spread = 1;
$font_spread = $largest - $smallest;
if ( $font_spread <= 0 )
$font_spread = 1;
$font_step = $font_spread / $spread;
// SQL cannot save you; this is a second (potentially different) sort on a subset of data.
if ( 'name' == $orderby )
uksort($counts, 'strnatcasecmp');
else
asort($counts);
if ( 'DESC' == $order )
$counts = array_reverse( $counts, true );
$a = array();
$rel = ( is_object($wp_rewrite) && $wp_rewrite->using_permalinks() ) ? ' rel="tag"' : '';
foreach ( $counts as $tag => $count ) {
$tag_id = $tag_ids[$tag];
$tag_link = clean_url($tag_links[$tag]);
$tag = str_replace(' ', ' ', wp_specialchars( $tag ));
$a[] = "\t<option value='$tag_link'>$tag ($count)</option>";
}
switch ( $format ) :
case 'array' :
$return =& $a;
break;
case 'list' :
$return = "<ul class='wp-tag-cloud'>\n\t<li>";
$return .= join("</li>\n\t<li>", $a);
$return .= "</li>\n</ul>\n";
break;
default :
$return = join("\n", $a);
break;
endswitch;
return apply_filters( 'dropdown_generate_tag_cloud', $return, $tags, $args );
}
Basically, I was just adding new parameter called tags_mode with the following parameter supported:
all
airport
state
And then, in dropdown_generate_tag_cloud(), I add this code:
if($tags_mode == 'airport'){
if(!(strtoupper($tag->name) == $tag->name))
continue;//skip current tag
} else if($tags_mode == 'state'){
if((strtoupper($tag->name) == $tag->name))
continue;//skip current tag
}
The main idea in this added snippet is this:
strtoupper($tag->name) == $tag->name
It work like this: if the uppercased tag name is equal to the original tag name. That means, current tag is already uppercased (or, equal to airport code).
To implement it, just do as the tutorial says. Only, you need to add new parameter:
<?php dropdown_tag_cloud('number=0&order=asc&tags_mode=state'); ?>
Notice the &tags_mode=state
Just try it out and tell me if this is what you want.

How to make a time limit for sockets?

How to make socket time limit ?
http://pastebin.com/0q3NeLAX
I tried socket_time_limit and others, but didnt help.
I want that if socket does not received any information, it will be closed after X seconds.
function QueryMinecraft( $IP, $Port = 25565 )
{
$Socket = Socket_Create( AF_INET, SOCK_STREAM, SOL_TCP );
if( $Socket === FALSE || #Socket_Connect( $Socket, $IP, (int)$Port ) === FALSE )
{
return FALSE;
}
Socket_Send( $Socket, "\xFE", 1, 0 );
$Len = Socket_Recv( $Socket, $Data, 256, 0 );
Socket_Close( $Socket );
if( $Len < 4 || $Data[ 0 ] != "\xFF" )
{
return FALSE;
}
$Data = SubStr( $Data, 3 );
$Data = iconv( 'UTF-16BE', 'UTF-8', $Data );
$Data = Explode( "\xA7", $Data );
return Array(
'HostName' => SubStr( $Data[ 0 ], 0, -1 ),
'Players' => isset( $Data[ 1 ] ) ? IntVal( $Data[ 1 ] ) : 0,
'MaxPlayers' => isset( $Data[ 2 ] ) ? IntVal( $Data[ 2 ] ) : 0
);
}
I would not use the sockets extension for this, I only use that for advanced socket operations that cannot be done using fsockopen(). The reason for this is that the sockets extension is not always available, whereas fsockopen() usually is.
Here is how I would write your code, with a data receive timeout:
function QueryMinecraft( $IP, $Port = 25565 )
{
// Seconds to wait for a successful connection
$connectTimeout = 5;
// Seconds to wait for data
$receiveTimeout = 5;
$Socket = fsockopen($IP, $port, $errNo, $errStr, $connectTimeout);
if( !$Socket || !stream_set_timeout( $Socket, $receiveTimeout ) )
{
return FALSE;
}
fwrite( $Socket, "\xFE" );
$Data = fread( $Socket, 256 );
fclose( $Socket );
if( strlen( $Data ) < 4 || $Data[ 0 ] != "\xFF" )
{
return FALSE;
}
$Data = SubStr( $Data, 3 );
$Data = iconv( 'UTF-16BE', 'UTF-8', $Data );
$Data = Explode( "\xA7", $Data );
return Array(
'HostName' => SubStr( $Data[ 0 ], 0, -1 ),
'Players' => isset( $Data[ 1 ] ) ? IntVal( $Data[ 1 ] ) : 0,
'MaxPlayers' => isset( $Data[ 2 ] ) ? IntVal( $Data[ 2 ] ) : 0
);
}

Categories