<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>MOleYArd (MOYA) blog</title>
	<atom:link href="http://www.moyablog.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.moyablog.com</link>
	<description>A Software Developer&#039;s Blog</description>
	<lastBuildDate>Sat, 07 Apr 2012 13:38:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>OWIDIG Tools new look</title>
		<link>https://www.moyablog.com/2012/04/07/owidig-tools-new-look/</link>
		<comments>https://www.moyablog.com/2012/04/07/owidig-tools-new-look/#comments</comments>
		<pubDate>Sat, 07 Apr 2012 13:38:02 +0000</pubDate>
		<dc:creator>MOYA</dc:creator>
				<category><![CDATA[Our products]]></category>
		<category><![CDATA[Quick news]]></category>
		<category><![CDATA[owidig html5 design look]]></category>

		<guid isPermaLink="false">http://www.moyablog.com/?p=932</guid>
		<description><![CDATA[<p>Enjoy OWIDIG Tools Facebook Album Photo Downloader new look at OWIDIG Tools </p> ]]></description>
			<content:encoded><![CDATA[<p>Enjoy OWIDIG Tools Facebook Album Photo Downloader new look at <a href="http://owidig.com/tools/photodownloader/facebook/" target="_blank">OWIDIG Tools</a><br />
<img src="http://www.moyablog.com/wp-content/uploads/2012/04/newlookowtools.png" alt="Screenshot of new OWIDIG tools look" title="Screenshot of new OWIDIG tools look" style="max-width: 100%;"/></p>
]]></content:encoded>
			<wfw:commentRss>https://www.moyablog.com/2012/04/07/owidig-tools-new-look/feed/</wfw:commentRss>
		<slash:comments>10547</slash:comments>
		</item>
		<item>
		<title>Wrapper PHP classes for prepared statements queries</title>
		<link>https://www.moyablog.com/2012/01/20/wrapper-php-classes-for-prepared-statements-queries/</link>
		<comments>https://www.moyablog.com/2012/01/20/wrapper-php-classes-for-prepared-statements-queries/#comments</comments>
		<pubDate>Fri, 20 Jan 2012 20:48:12 +0000</pubDate>
		<dc:creator>MOYA</dc:creator>
				<category><![CDATA[Web development]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[mysqli]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[prepared statements]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.moyablog.com/?p=838</guid>
		<description><![CDATA[<p style="text-align: justify;">It&#8217;s definitely a good practice to use prepared statements for SQL queries. Apart from other things, SQL injections are eliminated without necessity to escape data. For PHP and MySQL mysqli prepared statements are probably the most common prepared statements solution. But I don&#8217;t like one of their aspects.</p> <p></p> <p style="text-align: justify;">When dealing [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">It&#8217;s definitely a good practice to use <strong>prepared statements</strong> for <strong>SQL queries</strong>. Apart from other things, SQL injections are eliminated without necessity to escape data. For PHP and MySQL <strong>mysqli</strong> prepared statements are probably the most common prepared statements solution. But I don&#8217;t like one of their aspects.</p>
<p><span id="more-838"></span></p>
<p style="text-align: justify;">When dealing with SQL queries, most of the times you just need simply select or insert some data from/to a database. Very trivial task in its nature. We would probably expect this to be really short code to type. But it is not. Even though you don&#8217;t need to escape SQL data, there is a quantum of code to type for even the simplest query.</p>
<p>You at least need to:</p>
<ul>
<li>1. initialize a prepared statement</li>
<li>2. create the statement</li>
<li>3. bind variables to the statement as parameters (if there are any)</li>
<li>4. execute the statement</li>
<li>5. bind results to variables</li>
<li>6. fetch results</li>
<li>7. close the statement</li>
</ul>
<p style="text-align: justify;">in the case of SELECT statement. When you need to insert data the situation is similar, though slightly better.</p>
<p style="text-align: justify;">That doesn’t sound good at all. Six or seven steps and we just want to get some data from a database. And of course you have to type some <em>if</em> conditions, brackets and so on. Simply quite a long code for such a short actual task. And it even gets worse when we want to bind an array of parameters.</p>
<p style="text-align: justify;">I made some wrapper classes for the most common SQL tasks (or at least for the SQL tasks which I use most commonly). With them selecting data is reduced to two steps:</p>
<ul>
<li>1. define query</li>
<li>2. get results</li>
</ul>
<p style="text-align: justify;">Of course, these two steps just encapsulate previously mentioned (and in fact necessary) steps. But defining query to get results from a database was simply all we wanted, so with these classes it will be much easier and faster to write SQL prepared statements in PHP. So let&#8217;s show the implementations and the usage of aforementioned classes.</p>
<pre name="code" class="php">
//definitions for mysqli objects
define("HOST","localhost");
define("DBNAME","database");
define("USERNAME","username");
define("PASSWORD","password");
</pre>
<p><strong style="font-size: larger;">DBSelectQuery</strong></p>
<p><strong>Implementation:</strong></p>
<pre name="code" class="php">
class DBSelectQuery
{
    private $db;
    private $query;
    private $types;
    private $params;
    private $items;
    private $errorMessage;
    private $failure;

    public function __construct($db=null, $query,$params=array(),$types="")
    {
        if ($db!=null) $this->db=$db; else @$this->db = new mysqli(SQL_HOST, SQL_USERNAME, SQL_PASSWORD, SQL_DBNAME);
        if ($this->db->connect_errno)
        {
            $this->failure=true;
        }
        else
        {
            $this->db->set_charset("utf8");
            $this->query=$query;
            if (strcmp($types, "") == 0)
            {
                for ($i = 0; $i &lt; count($params);$i++)
                {
                    if (is_int($params[$i])) $types.="i";
                    elseif (is_double($params[$i])) $types.="d";
                    else  $types.="s";
                }
            }
            $this->types=$types;
            $this->params=$params;
            $this->failure=false;
            $this->selectQuery();
        }
    }

    public function setErrorMessage($message)
    {
       $this->errorMessage=$message;
    }          

    public function getResults($index=-1)
    {
        if ($this->failure == true)
        {
            if ($this->errorMessage != NULL) print $this->errorMessage;
            return FALSE;
        }
        if (is_string($index))
        {
           for ($i = 0; $i &lt; count($this->items); $i++) $results[]=$this->items[$i][$index];
           return $results;
        }
        else
        {
            if ($index &gt;= 0 &#038;&#038; $index &lt; count($this->items))
            return $this->items[$index];
            else return $this->items;
        }
    }

    public function getResult($name,$index=0)
    {
        if ($this->failure == true)
        {
            if ($this->errorMessage != NULL) print $this->errorMessage;
            return FALSE;
        }
        return $this->items[$index][$name];
    }    

    public function queryFailured()
    {
        return $this->failure;
    }

    private function selectQuery()
    {
        $selectStatement = $this->db->stmt_init();
        if ($selectStatement->prepare($this->query))
        {
          if (strcmp($this->types, "") != 0) call_user_func_array(array($selectStatement, "bind_param"), $this->refValues(array_merge(array($this->types), $this->params)));
          $selectStatement->execute();

          $meta = $selectStatement->result_metadata();

          while ($metaArray = $meta->fetch_field())
          {
              $parameters[] = &#038;$row[$metaArray->name];
          }
          call_user_func_array(array($selectStatement, 'bind_result'), $parameters);                

          while ($selectStatement->fetch())
          {
              foreach($row as $key => $value)
              {
                  $copy[$key] = $value;
              }
              $this->items[] = $copy;
          }
          if (!empty($selectStatement->error))
          {
              $this->failure=true;
          }
          $selectStatement->close();
        }
        else
        {
            $this->failure=true;
        }

    }

    private function refValues($arr)
    {
         if (strnatcmp(phpversion(),'5.3') &gt;= 0)
         {
             $refs = array();
             foreach($arr as $key => $value)
                 $refs[$key] = &#038;$arr[$key];
             return $refs;
         }
         return $arr;
    }
}
</pre>
<p><strong>Example usage:</strong></p>
<pre name="code" class="php">
@$db = new mysqli(HOST, USERNAME, PASSWORD, DBNAME);
if (mysqli_connect_errno()) die("Database connection error occured!"); 

$selectQuery = new DBSelectQuery($db,"SELECT id,name FROM table WHERE url = ? AND category_id = ?",array($URL,$kategoriaID),"si");
$results = $selectQuery->getResults(); //get array of all columns results
$selectQuery->setErrorMessage("Error occured!");
$rowResults = $selectQuery->getResults(2); //get array of all columns results in 3rd row of a result table
$nameResults = $selectQuery->getResults("name"); //get array of the name column results
$nameResult = $selectQuery->getResults("name"); //get value of the name column in 1st row of a result table
$nameResult = $selectQuery->getResult("name",0); //get value of the name column in 1st row of a result table
$nameResult = $selectQuery->getResult("name",2); //get value of the name column in 3rd row of a result table
print "Error did".($selectQuery->queryFailured() ? "":" not")." occured";
</pre>
<p><strong style="font-size: larger;">DBInsertQuery</strong></p>
<p><strong>Implementation:</strong></p>
<pre name="code" class="php">
class DBInsertQuery
{
    private $db;
    private $query;
    private $types;
    private $params;
    private $failure;

    public function __construct($db=null, $query,$params=array(),$types="")
    {
        if ($db!=null) $this->db=$db; else @$this->db = new mysqli(SQL_HOST, SQL_USERNAME, SQL_PASSWORD, SQL_DBNAME);
        if ($this->db->connect_errno)
        {
            $this->failure=true;
        }
        else
        {
            $this->db->set_charset("utf8");
            $this->query=$query;
            if (strcmp($types, "") == 0)
            {
                for ($i = 0; $i &lt; count($params);$i++)
                {
                    if (is_int($params[$i])) $types.="i";
                    elseif (is_double($params[$i])) $types.="d";
                    else  $types.="s";
                }
            }
            $this->types=$types;
            $this->params=$params;
            $this->failure=false;
            $this->insertQuery();
        }
    }

    public function queryFailured()
    {
        return $this->failure;
    }

    private function insertQuery()
    {
        $insertStatement = $this->db->stmt_init();
        if($insertStatement->prepare($this->query))
        {
          if (strcmp($this->types, "") != 0) call_user_func_array(array($insertStatement, "bind_param"), $this->refValues(array_merge(array($this->types), $this->params)));
          $insertStatement->execute();

          if (!empty($insertStatement->error))
          {
              $this->failure=true;
          }
          $insertStatement->close();
        }
        else $this->failure=true;
    }     

    private function refValues($arr)
    {
         if (strnatcmp(phpversion(),'5.3') >= 0)
         {
             $refs = array();
             foreach($arr as $key => $value)
                 $refs[$key] = &#038;$arr[$key];
             return $refs;
         }
         return $arr;
    }
}
</pre>
<p><strong>Example usage:</strong></p>
<pre name="code" class="php">
@$db = new mysqli(HOST, USERNAME, PASSWORD, DBNAME);
if (mysqli_connect_errno()) die("Database connection error occured!"); 

$insertQuery = new DBInsertQuery ($db,"INSERT INTO table  (name, category_id)  VALUES (?, ?)", array($name, $category_id),"si");
$insertQuery->setErrorMessage("Error occured!");
print "Error did".($insertQuery->queryFailured() ? "":" not")." occured";
</pre>
<p><strong style="font-size: larger;">DBTransactionQuery</strong></p>
<p><strong>Implementation:</strong></p>
<pre name="code" class="php">
class DBTransactionQuery
{
    private $db;
    private $query;
    private $message;

    public function __construct($db=null, $query, $message=NULL)
    {
        if ($db!=null) $this->db=$db; else @$this->db = new mysqli(SQL_HOST, SQL_USERNAME, SQL_PASSWORD, SQL_DBNAME);
        if ($this->db->connect_errno)
        {
            $this->failure=true;
        }
        else
        {
            $this->db->set_charset("utf8");
            if
            (
             strcasecmp($query, "start transaction") ||
             strcasecmp($query, "commit") ||
             strcasecmp($query, "rollback")
            )
            {
                $this->query=$query;
                $this->message=$message;
                $this->transactionQuery();
            }
        }
    }       

    private function transactionQuery()
    {
        $transactionStatement = $this->db->stmt_init();
        if ($transactionStatement->prepare($this->query))
        {
          $transactionStatement->execute();
          $transactionStatement->close();
        }
        if ($this->message != NULL) echo($this->message);
    }     

}
</pre>
<p><strong>Example usage:</strong></p>
<pre name="code" class="php">
@$db = new mysqli(HOST, USERNAME, PASSWORD, DBNAME);
if (mysqli_connect_errno()) die("Database connection error occured!"); 

new DBTransactionQuery($db,"START TRANSACTION");  

...
some other queries
...

if ($success == true)
{
new DBTransactionQuery($db,"COMMIT","Transation was successful.");
}
else
{
new DBTransactionQuery($db,"ROLLBACK","Transation failed.");
}
</pre>
<p>Note: DBInsertQuery  can of course be used for other queries (such as delete or update queries) where you don&#8217;t store query results.</p>
<p>You can download these classes <a href="http://www.moyablog.com/wrapper-php-classes-for-prepared-statements-queries/">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.moyablog.com/2012/01/20/wrapper-php-classes-for-prepared-statements-queries/feed/</wfw:commentRss>
		<slash:comments>5802</slash:comments>
		</item>
		<item>
		<title>Download Facebook albums with OWIDIG Tools</title>
		<link>https://www.moyablog.com/2012/01/11/download-facebook-albums-with-owidig-tools/</link>
		<comments>https://www.moyablog.com/2012/01/11/download-facebook-albums-with-owidig-tools/#comments</comments>
		<pubDate>Wed, 11 Jan 2012 11:50:51 +0000</pubDate>
		<dc:creator>MOYA</dc:creator>
				<category><![CDATA[Our products]]></category>
		<category><![CDATA[Utilities]]></category>
		<category><![CDATA[Album]]></category>
		<category><![CDATA[Download]]></category>
		<category><![CDATA[Downloader]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[OWIDIG]]></category>
		<category><![CDATA[OWIDIG tools]]></category>
		<category><![CDATA[Photoalbum]]></category>
		<category><![CDATA[photos]]></category>
		<category><![CDATA[pictures]]></category>
		<category><![CDATA[profile photos]]></category>
		<category><![CDATA[profile pictures]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.moyablog.com/?p=711</guid>
		<description><![CDATA[<p style="text-align: justify; clear: both;">In this article I will present you a way how to download complete Facebook photoalbums or profile photos with OWIDIG tools. Unlike most solutions that provide downloading Facebook albums, with OWIDIG tools you don&#8217;t need to install any additional software or browser plug-ins. All you need is your internet browser. Opera, [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify; clear: both;">In this article I will present you a way how to <strong>download complete Facebook photoalbums</strong> or <strong>profile photos</strong> with <strong>OWIDIG tools</strong>. Unlike most solutions that provide <strong>downloading Facebook albums</strong>, with <strong>OWIDIG tools</strong> you don&#8217;t need to install any additional software or browser plug-ins. All you need is your internet browser. Opera, Google Chrome and Microsoft Internet Explorer are supported.</p>
<p><span id="more-711"></span></p>
<p style="text-align: justify; clear: both;">There is a guide with all the steps how to <strong>download photos</strong> from <strong>Facebook</strong> on <strong>OWIDIG tools</strong> site. First thing you have to do is to open some <strong>Facebook album</strong> or <strong>profile photos</strong>. Then you need to paste this text &#8211; <em>javascript:&#8217;&lt;xmp&gt;&#8217;+window.document.body.parentNode.innerHTML+&#8217;&lt;/xmp&gt;&#8217;</em> &#8211; in the address bar in a tab (or a window) where you have that album opened. On some browsers you will have to type <em>javascript:</em> prefix manually because these browsers strip this prefix when you paste the text in the address bar. Some source code text will appear. We may ignore its exact content. Just select and copy all that text and return to <strong>OWIDIG tools</strong> again.</p>
<div style="margin-left: auto; margin-right: auto; text-align: center; clear: both;">
<iframe  width="640" height="480" style="max-width: 100%; border: 0px;" src="http://www.youtube.com/embed/YyUQygwmbjI" allowfullscreen="allowfullscreen"></iframe>
</div>
<p style="text-align: justify; clear: both;">There is a <strong>PASTE HERE</strong> input box. Paste copied text there and press <em>Get photos</em> button. Then three buttons will appear. <em>Show small images</em> and <em>Show large images</em> open a new tab or a window with all listed images, either thumbnails from the main album page or full-size photos. You can save them with browser&#8217;s <em>Save As</em> (or similar) option. The third button enable more advanced options with the help of Java applet, runnig of which will have to be approved, if you want to use it.</p>
<p style="text-align: justify; clear: both;">Using this applet you can set <strong>path for downloading</strong> and more importantly also <strong>filename prefix of images</strong>. The last option is to <strong>create a ZIP file with extracted photos</strong>. This option works well in Opera. It also works in Google Chrome, but only for albums with few photos due to Chrome URL length limitations. Setting filename prefix applies for ZIP archives as well.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.moyablog.com/2012/01/11/download-facebook-albums-with-owidig-tools/feed/</wfw:commentRss>
		<slash:comments>9823</slash:comments>
		</item>
		<item>
		<title>Grabbing and downloading website images with OWIDIG</title>
		<link>https://www.moyablog.com/2012/01/11/grabbing-and-downloading-website-images-with-owidig/</link>
		<comments>https://www.moyablog.com/2012/01/11/grabbing-and-downloading-website-images-with-owidig/#comments</comments>
		<pubDate>Wed, 11 Jan 2012 11:50:36 +0000</pubDate>
		<dc:creator>MOYA</dc:creator>
				<category><![CDATA[Our products]]></category>
		<category><![CDATA[Utilities]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[image downloader]]></category>
		<category><![CDATA[image grabber]]></category>
		<category><![CDATA[image info]]></category>
		<category><![CDATA[online service]]></category>
		<category><![CDATA[OWIDIG]]></category>
		<category><![CDATA[photos]]></category>
		<category><![CDATA[pictures]]></category>
		<category><![CDATA[social network sharing]]></category>
		<category><![CDATA[website image downloader]]></category>
		<category><![CDATA[website image grabber]]></category>

		<guid isPermaLink="false">http://www.moyablog.com/?p=709</guid>
		<description><![CDATA[<p style="text-align: justify; clear: both;">OWIDIG is an online image grabber and downloader of website images. I introduced it last month in this article. Since then several more features were added. This article contains detailed review of OWIDIG functionality.</p> <p style="text-align: justify; clear: both;">With OWIDIG service you can grab images from any website, view them, filter [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify; clear: both;"><strong>OWIDIG</strong> is an <strong>online image grabber</strong> and <strong>downloader</strong> of <strong>website images</strong>. I introduced it last month in <a href="http://www.moyablog.com/2011/12/22/owidig-image-extractor-finally-here/">this article.</a> Since then several more features were added. This article contains detailed review of <strong>OWIDIG</strong> functionality.</p>
<p style="text-align: justify; clear: both;">With <strong>OWIDIG</strong> service you can <strong>grab images from any website</strong>, view them, filter them, get information about them or download them. You may include or exclude images which are repeated. Moreover, CSS images (located inside style tags, external stylesheets (via link or import) and also inside inline styles) are supported as well. Images can be <strong>grabbed from sites</strong> with standard <strong>HTTP protocol</strong> as well as secure <strong>HTTPS protocol</strong>.</p>
<p><span id="more-709"></span></p>
<p style="text-align: justify; clear: both;">There are two basic modes &#8211; the <strong>LIST mode</strong> and the <strong>TABLE mode</strong>. In the list mode all images are listed one-by-one, side-by-side. We can hover over them to see more details. We may click on them to open them in a new window in their original dimensions. You can even <strong>share them via social networks or email</strong>. In the table mode we can see images in two tables &#8211; one table for standard HTML images, another one for images inside CSS. By clicking on column headers you can sort listed images according chosen property. The preview size of images in this mode might or might not be limited (by default it is limited to 330 pixels in both width and height).</p>
<p style="text-align: justify; clear: both;">Another feature is a <strong>deep grabbing</strong>. You may want to grab images from the whole website including all its subsections. <strong>OWIDIG</strong> enable users to grab images up to link depth of 10 for sitelinks that have the same domain as the original URL. Of course, the deep grabbing may sometimes take a significant amount of time, if there are many subsections. For grabbing from single URL there is one more option to <strong>grab images generated with JavaScript</strong>. This can be used when images aren&#8217;t in the original source code, but are in the code generated with JavaScript.</p>
<div style="margin-left: auto; margin-right: auto; text-align: center; clear: both;">
<iframe  width="640" height="480" style="max-width: 100%; border: 0px;" src="http://www.youtube.com/embed/HreizVp3CLw" allowfullscreen="allowfullscreen"></iframe>
</div>
<p style="text-align: justify; clear: both;"><strong>OWIDIG</strong> provides lots of <strong>filtering options</strong> to grab just those images you really want to grab. You can choose whether to include both standard and CSS images, or only ones of them. You can <strong>filter images by</strong> their <strong>dimensions</strong>, <strong>type</strong>, <strong>URL</strong>, <strong>filename</strong> and <strong>ordinal number</strong>. You can set <strong>user-agent</strong>, <strong>proxy</strong>, <strong>referrer</strong> and <strong>cookies</strong> to influence returned grabbed image content.</p>
<p style="text-align: justify; clear: both;">And finally we come to <strong>downloading of images</strong>. You can just <strong>list all images in a new window</strong> and then use saving capabilities of browser to save them. You may also use an applet. This applets requires user approval as it writes data &#8211; the images &#8211; to your hard drive. Using this applet you can <strong>set filenames and paths of downloaded images</strong>. In some browsers (Opera and Firefox support, partial Chrome support &#8211; for smaller archives) you can also <strong>create ZIP archive from images</strong> (you can set filenames of zipped images as well). </p>
<div style="margin-left: auto; margin-right: auto; text-align: center; clear: both;">
<iframe  width="640" height="480" style="max-width: 100%; border: 0px;" src="http://www.youtube.com/embed/nDdtszBKxCA" allowfullscreen="allowfullscreen"></iframe>
</div>
]]></content:encoded>
			<wfw:commentRss>https://www.moyablog.com/2012/01/11/grabbing-and-downloading-website-images-with-owidig/feed/</wfw:commentRss>
		<slash:comments>12515</slash:comments>
		</item>
		<item>
		<title>Essential Windows commands tips – part 3</title>
		<link>https://www.moyablog.com/2011/12/29/essential-windows-commands-tips-%e2%80%93-part-3/</link>
		<comments>https://www.moyablog.com/2011/12/29/essential-windows-commands-tips-%e2%80%93-part-3/#comments</comments>
		<pubDate>Thu, 29 Dec 2011 16:32:04 +0000</pubDate>
		<dc:creator>MOYA</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[bat]]></category>
		<category><![CDATA[batch files]]></category>
		<category><![CDATA[cmd]]></category>
		<category><![CDATA[command line]]></category>
		<category><![CDATA[command prompt]]></category>

		<guid isPermaLink="false">http://www.moyablog.com/?p=648</guid>
		<description><![CDATA[<p style="text-align: justify;">At the end of the previous part of this tutorial we briefly introduced echo command and I promised that we will deal with creating batch files in the command prompt. Actually, creating batch files is the second step. The first step is to create an arbitrary file.</p> <p></p> <p style="text-align: justify;">First let&#8217;s talk [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">At the end of the previous part of this tutorial we briefly introduced <strong>echo</strong> command and I promised that we will deal with creating batch files in the command prompt. Actually, creating batch files is the second step. The first step is to create an arbitrary file.</p>
<p><span id="more-648"></span></p>
<p style="text-align: justify;">First let&#8217;s talk about <strong>echo</strong> again. Type</p>
<pre name="code" class="vb:nocontrols">
echo /?
</pre>
<p style="text-align: justify;">to see how to use <strong>echo</strong> and what is its purpose. The output is:</p>
<pre name="code" class="vb:nocontrols">
Displays messages, or turns command-echoing on or off.

  ECHO [ON | OFF]
  ECHO [message]

Type ECHO without parameters to display the current echo setting.
</pre>
<p style="text-align: justify;">Last time we showed <em>turns command-echoing on or off</em> usage. This time <strong>ECHO [message]</strong> is the important one. Try few examples:</p>
<pre name="code" class="vb:nocontrols">
C:\Users\moya>echo text
text

C:\Users\moya>echo car
car
</pre>
<p style="text-align: justify;">Now we are almost done &#8211; we can echo text to the command line. Only other thing to do is to redirect that output to a file. Change current directory to <em>Desktop</em>:</p>
<pre name="code" class="vb:nocontrols">
cd Desktop
</pre>
<p style="text-align: justify;">and type:</p>
<pre name="code" class="vb:nocontrols">
echo car &gt; ourfile.txt
</pre>
<p style="text-align: justify;">In general <em>command > filename</em> redirect command output to a file. That&#8217;s exactly what we needed. Now ourfile.txt contains <em>car</em> string. Type</p>
<pre name="code" class="vb:nocontrols">
echo car &gt; ourfile.txt
</pre>
<p style="text-align: justify;">to see it. The file ourfile.txt will be opened and will contain <em>car</em> string.</p>
<p style="text-align: justify;">Now type</p>
<pre name="code" class="vb:nocontrols">
echo house &gt; ourfile.txt
</pre>
<p style="text-align: justify;">and open the file again. It now contains <em>house</em> string and <em>car</em> string was rewritten. What about not rewriting original content, but just appending it? It&#8217;s easy:</p>
<pre name="code" class="vb:nocontrols">
echo car &gt;&gt; ourfile.txt
</pre>
<p style="text-align: justify;">This will append echoed content to the end of the file. Its first line will now contain <em>house</em> and its second line <em>car</em>.</p>
<p style="text-align: justify;">Now try to echo some longer sentence:</p>
<pre name="code" class="vb:nocontrols">
echo This is a tutorial about essential Windows commands. &gt; ourfile.txt
</pre>
<p style="text-align: justify;">What if we would like to add several sentences (in separate line each). We can do this with several commands using append (&gt;&gt;). But we can also use one compound command. Try this:</p>
<pre name="code" class="vb:nocontrols">
echo This is a tutorial about essential Windows commands. &gt; ourfile.txt &#038;&#038; echo This is the second sentence. &gt;&gt; ourfile.txt
</pre>
<p style="text-align: justify;">We joined two commands with &#038;&#038;. Actually, we don&#8217;t have to open ourfile.txt in the external text editor. We can check output in command line as well with <strong>type</strong> command. Let&#8217;s type</p>
<pre name="code" class="vb:nocontrols">
type ourfile.txt
</pre>
<p style="text-align: justify;">and we will see the content of ourfile.txt file.</p>
<p style="text-align: justify;">Now we can probably imagine how to create batch files this way. It&#8217;s absolutely the same as the creation of any other file. We can see that this way of creating files is not at all practical, but it is one of the ways. But I guess you will rather use some text editor (though possibly command line based) for these kinds of tasks. We introduced this &#8211; &#038;&#038;. This stuff is much more practical. It serves for chaining commands. There are more types of chainings:</p>
<ul>
<li><span style="display:-moz-inline-stack; display: inline-block; width: 175px;"><strong>command1 &#038;  command2</strong></span> Run command1 and  then command2</li>
<li><span style="display:-moz-inline-stack; display: inline-block; width: 175px;"><strong>command1 &#038;&#038; command2</strong></span> Run command1 and if commandA succeeds then run command2</li>
<li><span style="display:-moz-inline-stack; display: inline-block; width: 175px;"><strong>command1 || command2</strong></span> Run command1 and if it fails then run command2</li>
</ul>
<p style="text-align: justify;">You can use these when you write your own batch files or if you use more complicated compound commands. We now know something about redirection of an output. Besides printing output applications (and thus their commands) might also have some input. An output of one application (command) may serve as an input for another one. We have actually encountered this when we used command <strong>tree</strong> (<em>tree | more</em>). But we haven&#8217;t yet really explained what it exactly does.</p>
<ul>
<li><span style="display:-moz-inline-stack; display: inline-block; width: 175px;"><strong>command1  |  command1</strong></span> Pipe the output from command1 into command2</li>
</ul>
<p style="text-align: justify;">It pipes output. It exactly means that the output of the command is served as the input for the another command. Utility <strong>more</strong> takes output of another command and then print it line-by-line or page-by-page when user press <em>Enter</em> or <em>Space</em>. So that&#8217;s all for this part <img src='https://www.moyablog.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>https://www.moyablog.com/2011/12/29/essential-windows-commands-tips-%e2%80%93-part-3/feed/</wfw:commentRss>
		<slash:comments>10495</slash:comments>
		</item>
		<item>
		<title>OWIDIG image extractor finally here</title>
		<link>https://www.moyablog.com/2011/12/22/owidig-image-extractor-finally-here/</link>
		<comments>https://www.moyablog.com/2011/12/22/owidig-image-extractor-finally-here/#comments</comments>
		<pubDate>Thu, 22 Dec 2011 23:20:42 +0000</pubDate>
		<dc:creator>MOYA</dc:creator>
				<category><![CDATA[Our products]]></category>
		<category><![CDATA[Utilities]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[image downloader]]></category>
		<category><![CDATA[image grabber]]></category>
		<category><![CDATA[image info]]></category>
		<category><![CDATA[online service]]></category>
		<category><![CDATA[OWIDIG]]></category>
		<category><![CDATA[photos]]></category>
		<category><![CDATA[pictures]]></category>
		<category><![CDATA[social network sharing]]></category>
		<category><![CDATA[website image downloader]]></category>
		<category><![CDATA[website image grabber]]></category>

		<guid isPermaLink="false">http://www.moyablog.com/?p=575</guid>
		<description><![CDATA[<p style="text-align: justify;">In the previous post I have written few things about development of OWIDIG &#8211; image grabber (or image extractor) and image downloader.</p> <p style="text-align: justify;"> Today I can announce that OWIDIG is finally officially released. Instead of writing some sort of text blog I decided to present the following video: </p> <p>&#160;</p> <p [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">In the previous post I have written few things about development of <strong>OWIDIG</strong> &#8211; <strong>image grabber</strong> (or <strong>image extractor</strong>) and <strong>image downloader.</strong></p>
<p style="text-align: justify;">
Today I can announce that <strong>OWIDIG</strong> is finally officially released. Instead of writing some sort of text blog I decided to present the following video:
</p>
<p>&nbsp;</p>
<div style="text-align: justify; background: black;">
<div style="margin-left: auto; margin-right: auto; width: 640px; max-width: 100%;">
<iframe  width="640" height="480" style="max-width: 100%; border: 0px;" src="http://www.youtube.com/embed/Zxf2FVFvUv8" allowfullscreen="allowfullscreen"></iframe>
</div>
</div>
<p style="text-align: justify;">So visit <a href="http://www.owidig.com" title="OWIDIG">OWIDIG</a> &#8211; <strong>MOYA&#8217;s OWIDIG (Online Webpage Image Downloader and ImageInfo Grabber) Service</strong>, try it yourself and enjoy the service. I am looking forward to any kind of feedback as well.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.moyablog.com/2011/12/22/owidig-image-extractor-finally-here/feed/</wfw:commentRss>
		<slash:comments>10229</slash:comments>
		</item>
		<item>
		<title>OWIDIG image extractor development in progress</title>
		<link>https://www.moyablog.com/2011/11/30/owidig-image-extractor-development-in-progress/</link>
		<comments>https://www.moyablog.com/2011/11/30/owidig-image-extractor-development-in-progress/#comments</comments>
		<pubDate>Wed, 30 Nov 2011 15:13:43 +0000</pubDate>
		<dc:creator>MOYA</dc:creator>
				<category><![CDATA[Our products]]></category>
		<category><![CDATA[Utilities]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[image downloader]]></category>
		<category><![CDATA[image grabber]]></category>
		<category><![CDATA[image info]]></category>
		<category><![CDATA[online service]]></category>
		<category><![CDATA[OWIDIG]]></category>
		<category><![CDATA[photos]]></category>
		<category><![CDATA[pictures]]></category>
		<category><![CDATA[social network sharing]]></category>
		<category><![CDATA[website image downloader]]></category>
		<category><![CDATA[website image grabber]]></category>

		<guid isPermaLink="false">http://www.moyablog.com/?p=535</guid>
		<description><![CDATA[<p style="text-align: justify;">I am currently working on OWIDIG (Online Webpage Image Downloader and ImageInfo Grabber). You can see its current published state here &#8211; OWIDIG. It has &#8220;old&#8221; inside URL, as I plan to keep this quasi-beta version available online.</p> <p style="text-align: justify;">So let me introduce you OWIDIG.</p> <p></p> <p style="text-align: justify;">As its name implies [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">I am currently working on <strong>OWIDIG</strong> (Online Webpage Image Downloader and ImageInfo Grabber). You can see its current published state <a href="http://oldowidig.moya.sk/" title="OWIDIG">here &#8211; OWIDIG</a>. It has &#8220;old&#8221; inside URL, as I plan to keep this quasi-beta version available online.</p>
<p style="text-align: justify;">So let me introduce you OWIDIG.</p>
<p><span id="more-535"></span></p>
<p style="text-align: justify;">As its name implies its primary goal is to <strong>grab</strong> some <strong>image content</strong> and <strong>information</strong> from <strong>websites</strong>. One feature is to list all images with specific information such as filename, filetype, dimensions or description. One of the most important questions is (though not always <img src='https://www.moyablog.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ) the applicability. It&#8217;s quite straightforward. You might be a webdeveloper who wants ho have overview of all image content on his or someone&#8217;s else site. You may work on application that needs to grab all profile photos that always have particular dimensions. OWIDIG at its current state provides lots of filtering options considering dimensions, type, URL, browser access or kind of images (normal images or images included within styles).</p>
<p style="text-align: justify;">
<img src="http://www.moyablog.com/wp-content/uploads/2011/11/oldowidigscreen.png" alt="Screenshot of development version of OWIDIG service" title="Screenshot of development version of OWIDIG service" style="max-width: 100%;"/>
</p>
<p style="text-align: justify;">Another important feature implied both by name &#8220;grabber&#8221; and mainly &#8220;downloader&#8221; is an <strong>ability</strong> to <strong>download images</strong>. Two methods are used, one which use saving capabilities of browsers, the another (more powerful) which use an applet. The latter method enable users to choose saving path for images as well as filename prefix. This may save a significant amount of time. You may want to download a photo album from website with photos. Their filenames might not be what you want. So you just type its name prefix and your images will be saved with filename starting with prefix + their number.</p>
<p style="text-align: justify;">Final version of <strong>OWIDIG</strong> will also provide <strong>social network sharing capabilities</strong> and its current design will be considerably redesigned to make it better arranged and more simple (advanced options will be hidden by default) to make it more usable for the less-technical users. For now &#8211; just try the current version and look forward to the final version. Its release will be soon <img src='https://www.moyablog.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p style="text-align: justify;"><big><strong>UPDATE (December 3rd):</strong> Lots of updates to come in the final version are now available in the current version available <a href="http://oldowidig.moya.sk/" title="OWIDIG">here</a>. This includes the new type of listing and social network sharing.</big></p>
]]></content:encoded>
			<wfw:commentRss>https://www.moyablog.com/2011/11/30/owidig-image-extractor-development-in-progress/feed/</wfw:commentRss>
		<slash:comments>10133</slash:comments>
		</item>
		<item>
		<title>How to validate custom attributes of HTML elements in W3C validator?</title>
		<link>https://www.moyablog.com/2011/11/17/how-to-validate-custom-attributes-of-html-elements-in-w3c-validator/</link>
		<comments>https://www.moyablog.com/2011/11/17/how-to-validate-custom-attributes-of-html-elements-in-w3c-validator/#comments</comments>
		<pubDate>Thu, 17 Nov 2011 21:41:41 +0000</pubDate>
		<dc:creator>MOYA</dc:creator>
				<category><![CDATA[Utilities]]></category>
		<category><![CDATA[Web development]]></category>
		<category><![CDATA[AddThis]]></category>
		<category><![CDATA[attributes]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[doctype]]></category>
		<category><![CDATA[DTD]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[strict]]></category>
		<category><![CDATA[target]]></category>
		<category><![CDATA[transitional]]></category>
		<category><![CDATA[validation]]></category>
		<category><![CDATA[Validator]]></category>
		<category><![CDATA[W3C]]></category>
		<category><![CDATA[XHTML]]></category>
		<category><![CDATA[XML namespaces]]></category>

		<guid isPermaLink="false">http://www.moyablog.com/?p=463</guid>
		<description><![CDATA[<p style="text-align: justify;">Sometimes you need to use (X)HTML element attributes that are not part of any W3C standard doctypes. Or you may want to use strict version of doctype with some attributes that are only in transitional version of doctype. Well, it certainly has its reasons (I will mention it) why they were removed and [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Sometimes you need to use <strong>(X)HTML</strong> element attributes that are not part of any W3C standard doctypes. Or you may want to use <strong>strict version of doctype </strong>with some attributes that are only in <strong>transitional version of doctype</strong>. Well, it certainly has its reasons (I will mention it) why they were removed and if you would like to use strict doctype then you shouldn&#8217;t use them. </p>
<p style="text-align: justify;">Most of the time, you can follow this rule. In fact, you should use strict doctype instead of transitional doctype where possible. In strict versions of doctypes <strong>presentation attributes</strong> are removed and are expected to be replaced with <strong>CSS properties</strong>. I prefer strict doctypes. Apart from other things modern browsers use their most standards compliant rendering mode and therefore it is easier to make appearance of the site look exactly the same in various browsers. (commonly spaces between elements may be problematic)</p>
<p><span id="more-463"></span></p>
<p style="text-align: justify;">But let me tell you a counterexample. It is the <em>target</em> attribute of the anchor (a) element. I agree that it&#8217;s a presentation matter. And <strong>CSS3</strong> actually implements support for it (look at <a href="http://www.w3.org/TR/css3-hyperlinks/" title="CSS3 hyperlinks draft" target="_blank">CSS3 hyperlinks draft</a>). But support for this CSS3 property is still not sufficient enough. But what if we want to use <strong>strict doctype</strong>, while still using <strong>target</strong> attribute, not using <strong>any CSS3</strong> (which not may be supported by visitors&#8217; browsers) <strong>nor JavaScript</strong> (which may be disabled), but still want to pass <strong>W3C validation test</strong>?</p>
<p style="text-align: justify;">Another example when we might need to use custom attributes is when we use <a href="http://www.addthis.com" title="AddThis" target="_blank">AddThis</a> service for sharing content on social networks. When you use this service you may want to specify custom sharing settings. To accomplish this, you need to add attributes like <em>addthis:url</em> or <em>addthis:title</em>.</p>
<p style="text-align: justify;">They actually propose some solutions on their Help site to make it valid. One solution is adding a custom namespace:</p>
<pre name="code" class="html">
&lt;html
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:addthis="http://www.addthis.com/help/api-spec"&gt;
</pre>
<p style="text-align: justify;">As they mention, external custom namespaces are ignored by <strong>W3C validator</strong>. What you can do is to use inline extensions to your doctype definition (<strong>DTD</strong>). Here I will give an example that solves previously mentioned problems.</p>
<pre name="code" class="html">
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
[
  &lt;!ATTLIST div addthis:url CDATA #IMPLIED&gt;
  &lt;!ATTLIST div addthis:title CDATA #IMPLIED&gt;
  &lt;!ATTLIST a target CDATA #IMPLIED&gt;
]&gt;
</pre>
<p style="text-align: justify;">
This is the solution, you will validate your page using these inline extensions. But it is just a partial solution because (as is also mentioned on AddThis Help site) most browsers render the trailing ]&gt; in the page itself. I have tested it in several browsers (current versions) and out of them only Opera (update: this applied for Opera 11.5x, but not anymore for Opera 11.60) browser treated this correctly without rendering. AddThis Help does not offer any solution here… But luckily this is not so big problem and there is a solution. We just need some CSS to fix it:</p>
<pre name="code" class="css">
html{color: transparent;}
div#wrapper{color: black;}
</pre>
<p style="text-align: justify;">The whole trick is setting global font color transparent which will hide trailing ]&gt; and then insert wrapper div in body tag (or possibly somewhere else) with font color we need. There is one more thing to mention for XHTML documents. Colon inside attributes has a special meaning, it denotes namespace prefix. In case of <em>addthis:url</em> and <em>addthis:url</em> it is namespace prefix <em>addthis</em>. Although external custom namespaces (their content) are ignored by <strong>W3C Validator</strong>, namespace prefixes still need to be included to pass validation (otherwise validator will state that a prefix for an attribute on an element is not defined), like this (look at line 3): </p>
<pre name="code" class="html">
&lt;html
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:addthis="http://www.addthis.com/help/api-spec"&gt;
</pre>
<p style="text-align: justify;">Actually, because external content is ignored this</p>
<pre name="code" class="html">
&lt;html
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:addthis=""&gt;
</pre>
<p style="text-align: justify;">is actually enough. In case of HTML document colon (:) has actually no special meaning because the HTML syntax does not support namespace declarations. So you can simply stay with <em>&lt;html&gt;</em>.</p>
<p style="text-align: justify;"> So that&#8217;s it &#8211; the way to validate custom attributes of HTML elements in W3C validator.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.moyablog.com/2011/11/17/how-to-validate-custom-attributes-of-html-elements-in-w3c-validator/feed/</wfw:commentRss>
		<slash:comments>9055</slash:comments>
		</item>
		<item>
		<title>Essential Windows commands tips – part 2</title>
		<link>https://www.moyablog.com/2011/11/02/essential-windows-commands-tips-%e2%80%93-part-2/</link>
		<comments>https://www.moyablog.com/2011/11/02/essential-windows-commands-tips-%e2%80%93-part-2/#comments</comments>
		<pubDate>Wed, 02 Nov 2011 15:15:29 +0000</pubDate>
		<dc:creator>MOYA</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[bat]]></category>
		<category><![CDATA[batch files]]></category>
		<category><![CDATA[cmd]]></category>
		<category><![CDATA[command line]]></category>
		<category><![CDATA[command prompt]]></category>

		<guid isPermaLink="false">http://www.moyablog.com/?p=391</guid>
		<description><![CDATA[<p style="text-align: justify;">Today I will move on with the second part of the article about Windows command tips. This part will discuss how to create and edit batch files.</p> <p></p> Creating batch files <p style="text-align: justify;">Batch files can be created in graphical environment of Windows as well as in CMD. While there are lots of [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Today I will move on with the second part of the article about Windows command tips. This part will discuss how to create and edit batch files.</p>
<p><span id="more-391"></span></p>
<h3>Creating batch files</h3>
<p style="text-align: justify;">Batch files can be created in graphical environment of Windows as well as in CMD. While there are lots of tasks that are much more efficient to be conducted in CMD, in the case of creating batch files I find it more convenient to do it in GUI environment.</p>
<p style="text-align: justify;">Just right-click on empty area of any folder or desktop and select New -&gt; Text Document. This will create an empty plain-text document in the folder named &#8220;New Text Document.txt&#8221; or similar name (possibly with a number in brackets if there were previously created empty text documents this way). Now click on it once, wait for a while and click on it second time (or click and press F2, or right-click and select Rename). The filename will be highlighted. Rename the filename and change the extension <em>.txt</em> to <em>.bat</em>.</p>
<p style="text-align: justify;">There is one common feature (but at least in my opinion issue) in Microsoft Windows operating systems that is in newer versions set to be default, which is really a shame. It is <em>Hide extensions for known file types</em> folder option. When I work on someone&#8217;s else computer, they actually often have this enabled… It has some pseudoaesthetic motivation of hiding these extensions, but otherwise it&#8217;s highly impractical. If you have this option enabled, you will not see .txt part of the filename. If you add it manually, you actually get <em>filename.txt.txt</em> or in a case of .bat <em>filename.txt.bat</em>. So if this is the case open any folder (for example (My) Computer folder). Choose <em>Tools -&gt; Folder options…</em> from the file menu (if you don&#8217;t see it, press Alt + F and it will show up). Then <em>Folder Options</em> window will appear. Select <em>View</em> tab and in the <em>Advanced settings:</em> list uncheck <em>Hide extensions for known file types</em> option. Now you can return to the previous step.</p>
<p style="text-align: justify;">In Windows NT, 2000, XP, Vista and 7 you can use <em>cmd</em> extension instead of <em>bat</em>. In old Windows 9x versions and in DOS you could use just <em>.bat</em>. (Command prompt cmd.exe can handle both <em>.cmd</em> and.<em>bat</em>, command.com only <em>.bat</em>). We might say that it would be correct to use <em>.bat</em> extension for command.com and newer <em>.cmd</em> for cmd.exe, but this is actually not the case. Because simply people are get used to <em>bat</em> and it&#8217;s still much more common. There are some (truly) minor differences between the two, but most of the time they are absolutely interchangeable in modern Windows operating system.</p>
<h3>Editing batch files</h3>
<p style="text-align: justify;">After creating the batch file, open it in some plain-text editor (Notepad is just enough). We have introduced some basic commands in the previous part of this article. So let&#8217;s type</p>
<pre name="code" class="vb:nocontrols">
dir
</pre>
<p style="text-align: justify;">and save the file. Now we can run test.bat (suppose that we named it so). A window will appear very shortly and then disappear.</p>
<p style="text-align: justify;">To prevent this add <em>pause</em> command in the second line.</p>
<pre name="code" class="vb:nocontrols">
dir
pause
</pre>
<p style="text-align: justify;">Now the window will stay open and its output will be similar to this:</p>
<pre name="code" class="vb:nocontrols">
C:\Users\moya\Desktop\bat-test>dir
 Volume in drive C has no label.
 Volume Serial Number is 20EB-818C

 Directory of C:\Users\moya\Desktop\bat-test

02. 11. 2011  11:36    &lt;DIR&gt;          .
02. 11. 2011  11:36    &lt;DIR&gt;          ..
02. 11. 2011  12:07                10 test.bat
               1 File(s)             10 bytes
               2 Dir(s)  747 433 140 224 bytes free

C:\Users\moya\Desktop\bat-test>pause
Press any key to continue . . .
</pre>
<p style="text-align: justify;">The <strong>pause</strong> command caused the suspension of processing of a batch program and the last line now contains <em>Press any key to continue . . .</em> message. Processing will continue after pressing any key as message states. Of course <strong>pause</strong> command may be inserted anywhere in the file, not just at the end, for example:</p>
<pre name="code" class="vb:nocontrols">
dir
pause
dir
pause
</pre>
<p style="text-align: justify;">Another thing you may notice are lines <em>C:\Users\moya\Desktop\bat-test>dir</em> and <em>C:\Users\moya\Desktop\bat-test>pause</em>. It appears as if we had typed these commands manually in the command prompt, but we hadn&#8217;t. To prevent this behavior you can preppend <em>@</em> sign before each command like this:</p>
<pre name="code" class="vb:nocontrols">
@dir
@pause
</pre>
<p style="text-align: justify;">Now the output will be:</p>
<pre name="code" class="vb:nocontrols">
 Volume in drive C has no label.
 Volume Serial Number is 20DA-972D

 Directory of C:\Users\moya\Desktop\bat-test

02. 11. 2011  11:36    &lt;DIR&gt;          .
02. 11. 2011  11:36    &lt;DIR&gt;          ..
02. 11. 2011  12:44                12 test.bat
               1 File(s)             12 bytes
               2 Dir(s)  747 431 907 328 bytes free
Press any key to continue . . .
</pre>
<p style="text-align: justify;">It&#8217;s a bit awkward to preppend <em>@</em> before every command. Luckily, there is a way to apply this behavior globally. Try:</p>
<pre name="code" class="vb:nocontrols">
@echo off
dir
pause
</pre>
<p style="text-align: justify;">The effect is the same. <strong>echo off</strong> applies demanded behavior for all following commands in the batch file and @ <strong>echo off</strong> applies this to that command itself.</p>
<p style="text-align: justify;">We introduced <strong>echo</strong> command. This command is also useful when we are creating batch files in the command prompt. We will tell more about it in the next part of this series <img src='https://www.moyablog.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
]]></content:encoded>
			<wfw:commentRss>https://www.moyablog.com/2011/11/02/essential-windows-commands-tips-%e2%80%93-part-2/feed/</wfw:commentRss>
		<slash:comments>9070</slash:comments>
		</item>
		<item>
		<title>How to convert relative URLs to absolute URLs in websites using PHP</title>
		<link>https://www.moyablog.com/2011/10/19/how-to-convert-relative-urls-to-absolute-urls-in-websites-using-php/</link>
		<comments>https://www.moyablog.com/2011/10/19/how-to-convert-relative-urls-to-absolute-urls-in-websites-using-php/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 15:37:00 +0000</pubDate>
		<dc:creator>MOYA</dc:creator>
				<category><![CDATA[Web development]]></category>
		<category><![CDATA[absolute URL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[regexps]]></category>
		<category><![CDATA[regular expressions]]></category>
		<category><![CDATA[relative URL]]></category>
		<category><![CDATA[URL]]></category>
		<category><![CDATA[URL conversion]]></category>

		<guid isPermaLink="false">http://www.moyablog.com/?p=156</guid>
		<description><![CDATA[<p style="text-align: justify;">You will probably not argue that relative URLs (Uniform Resource Locators) are very useful feature of websites, especially as for web creation process. If once some webpage had to move somewhere else (and it usually has to at least from developer&#8217;s localhost to production environment), it would be a tedious process to rewrite [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">You will probably not argue that relative URLs (Uniform Resource Locators) are very useful feature of websites, especially as for web creation process. If once some webpage had to move somewhere else (and it usually has to at least from developer&#8217;s localhost to production environment), it would be a tedious process to rewrite it, so using relative addresses is very convenient.</p>
<p style="text-align: justify;">But there are situations when absolute URLs better fit our needs, or when they are even essential. A typical example is when you want to copy the source of some website or its part. There are relative URLs for images and included styles. Of course, you want to use it in another domain, so relative URLs are not what you want, if you don&#8217;t want to also copy all included content. Another example of usage is when you want to download that included content. Again, you need to have its absolute URL.</p>
<p style="text-align: justify;">So the task is to convert all relative URL addresses to their absolute counterparts. But before I show you how to this, let&#8217;s discuss occurences and all possible forms of relative URLs. We will deal with HTTP(S) scheme URLs.</p>
<p><span id="more-156"></span></p>
<p style="text-align: justify;">The most common occurrences of URLs in websites have these forms:</p>
<pre name="code" class="html">
&lt;img src="someurl.jpg" alt="someurl" /&gt;

&lt;a href="subsite/index.html"&gt;&lt;/a&gt;

&lt;script type="text/javascript" src="scriptinurl.js"&gt;&lt;/script&gt;

&lt;link rel="stylesheet" type="text/css" href="styles.css" /&gt;

&lt;div style="background: url('image.jpg')"&gt;&lt;/div&gt;

&lt;style type="text/css"&gt;
/*&lt;![CDATA[*/
 @import url('url.css');
 p {background: url("image.jpg")}
/*]]&gt;*/
&lt;/style&gt;
</pre>
<p style="text-align: justify;">So we may have URL as <em>href</em> or <em>src</em> attribute of an element, or we may have URL inside a CSS style within <em>url()</em>. These include the vast majority of included URLs. There is one more type &#8211; URL defined inside internal script (like dynamically replaced or inserted images). We will not deal with this situation, because it&#8217;s simply not always possible to cover it in an universal way. Such an URL is often built up from several parts (different variables, substrings, values returned from functions, …). There is no unified form in that case, but after reading this article you will be able to adjust presented solution for those special cases.</p>
<p style="text-align: justify;">As for URLs as attributes, they may be surrounded by single or double quotes and between quotes and URL can be placed white spaces (browser will parse URL with leading spaces)</p>
<pre name="code" class="html">
&lt;element src="url"&gt;&lt;/element&gt;
&lt;element src=" url"&gt;&lt;/element&gt;
&lt;element src="url "&gt;&lt;/element&gt;
&lt;element src="   url   "&gt;&lt;/element&gt;
&lt;element src='url'&gt;&lt;/element&gt;
&lt;element src=' url'&gt;&lt;/element&gt;
&lt;element src='  url  '&gt;&lt;/element&gt;
</pre>
<p style="text-align: justify;">The same thing about white spaces applies to URLs inside CSS <em>url()</em>. Moreover, apart from single and double quotes, in the case of CSS URLs no quotes are required. So we have these options:</p>
<pre name="code" class="css">
 url("someurl");
 url('someurl');
 url(someurl);
</pre>
<p style="text-align: justify;">That&#8217;s all about possible occurrences, let&#8217;s move to possible forms of relative URLs.</p>
<p style="text-align: justify;  font-size: large;"><strong>1.</strong> Relative URL that does not begin with slashes, e.g. <em>page.html</em>, <em>subsite/page.html</em>, <em>~subsite/page.html</em>, <em>images/image.gif</em></p>
<p style="text-align: justify;">This is the most common case. This kind of URL has a path that links URL from a directory of the current page. (current page&#8217;s directory is &#8220;hidden&#8221; root of URL)</p>
<p style="text-align: justify;  font-size: large;"><strong>2.</strong> Relative URL that begins with <em>./</em>, e.g. <em>./page.html</em>, <em>./subsite/page.html</em>, <em>./~subsite/page.html</em>, <em>./images/image.gif</em></p>
<p style="text-align: justify;">This is the same as the first case with <em>.</em> denoting the current directory.</p>
<p style="text-align: justify;  font-size: large;"><strong>3.</strong> Relative URL that begins with <em>../</em>, <em>../../</em>, <em>../../../</em> and so on, e.g. <em>../page.html</em>, <em>../../subsite/page.html</em>, <em>../../image.gif</em></p>
<p style="text-align: justify;">In this case &#8216;hidden&#8217; root of URL is current page&#8217;s parent directory (in case of <em>../</em>), or the parent directory of current page&#8217;s parent directory (in case of <em>../../</em>) and so on.</p>
<p style="text-align: justify;  font-size: large;"><strong>4.</strong> Relative URL that begins with <em>/</em>, e.g. <em>/page.html</em>, <em>/subsite/page.html</em>, <em>/images/image.gif</em></p>
<p style="text-align: justify;">In this case &#8216;hidden&#8217; root of URL is the real root directory of the server and it is irrelevant in which subdirectory is the current page.</p>
<p style="text-align: justify;  font-size: large;"><strong>5.</strong> Relative URL that begins with <em>//</em>, e.g. <em>//www.webpage.com</em>, <em>//examplepage.net</em></p>
<p style="text-align: justify;">This is almost an absolute path, but what is missing is an URI scheme (like <em>http</em>, or <em>https</em>). Actually, the practical use of this is might be when both standard nonsecure and secure protocol versions of a different domain site exist and we want to retain current site&#8217;s URI scheme. Yes, to say it explicitly, missing URI scheme is supplemented with current site&#8217;s URI scheme.</p>
<p style="text-align: justify;  font-size: large;"><strong>6.</strong> Relative URLs of all previous types that contain <em>../</em> and <em>./</em> scattered inside URL, e.g. <em>subpage/../page.html</em>, <em>/subsite/././page.html</em>, <em>/images/../images/../images/./image.gif</em>, <em>//examplepage.net/page/../page/</em></p>
<p style="text-align: justify;">This &#8216;type&#8217; is not at all practical and kind of crazy and you should not encounter it often, but it is still valid to use these current and parent directories symbols in the other parts of an URL than in the beginning of an URL, so you have to take in mind the possibility of encountering this.</p>
<div>
<hr /></div>
<p style="text-align: justify;">Now we know theoretical stuff about relative URLs, so let&#8217;s finally move on the conversion functions themselves.</p>
<p style="text-align: justify;">The first function I will show you convert a relative URL to an absolute URL given that it has both the base absolute URL and the relative URL as parameters. We assume that we have already gained this relative URL from somewhere and now we just want to convert it. So here is the function and then the explanation follows:</p>
<pre name="code" class="php">
function convertRelativeToAbsoluteURL($baseAbsoluteURL, $relativeURL)
{
   $relativeURL = trim($relativeURL);
   if (substr($relativeURL, 0, 7) !== 'http://' &#038;&#038; substr($relativeURL, 0, &#56;) !== 'https://')
   {
    while (strpos($relativeURL, '/./') !== false)
    {
       $relativeURL=str_replace('/./','/',$relativeURL);
    }
    if (substr($relativeURL, 0, 2) === './') $relativeURL = substr($relativeURL, 2);
    $urlInfo = parse_url($baseAbsoluteURL);
    if ($urlInfo == false) return false;
    $urlBasePath = substr($urlInfo['path'], 0, strrpos($urlInfo['path'],"/"));
    $dirDepth = substr_count($urlInfo['path'], '/')-1;

    $dirDepthRel = substr_count(preg_filter('\'^((\\.\\./)+)(.*)\'', '$1', $relativeURL), '../');
    $relativeURL = preg_replace('\'^((\\.\\./)+)(.*)\'', '$3', $relativeURL);    

    for ($i=0; $i&lt;$dirDepthRel; $i++)
    {
       $urlBasePath = substr($urlBasePath, 0, strrpos($urlBasePath,"/"));
    }
    $urlBase = $urlInfo['scheme'].'://'.$urlInfo['host'].$urlBasePath;

    do
    {
       $tempContent = $relativeURL;
       $relativeURL = preg_replace('\'^(.*?)(([^/]*)/\\.\\./)(.*?)$\'', '$1$4', $relativeURL);
    }
    while ($tempContent != $relativeURL);

    if(substr($relativeURL, 0, 2) === "//")
    {
       $relativeURL=$urlInfo['scheme'].':'.$relativeURL;
    }
    else if(substr($relativeURL, 0, 1) === "/")
    {
       $relativeURL=$urlInfo['scheme'].'://'.$urlInfo['host'].$relativeURL;
    }
    else
    {
       $relativeURL=$urlBase.'/'.$relativeURL;
    }
   }
   return $relativeURL;
}
</pre>
<p style="text-align: justify;">I will not explain single used built-in PHP functions in the details, you can find complete explanations of them for example in <a href="http://php.net/manual/" title="PHP Manual">PHP manual</a>, the site you definitely know <img src='https://www.moyablog.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . However, I will cover regular expressions (regexps) functions a bit, as we used them a lot in presented functions.</p>
<p style="text-align: justify;">The most convenient way of using regexps in PHP is the use of Perl-Compatible Regular Expressions (PCRE). There are some differences from POSIX regexps, but I will not bother with this. We will use three functions &#8211; <em>preg_filter</em>, <em>preg_replace</em> and <em>preg_replace_callback</em>. They are all quite similar &#8211; difference between <em>preg_filter</em> and <em>preg_replace</em> is that the latter returns original string, where replacements should have taken place, every time, while the first one if and only if some replacements occured, otherwise it returns NULL. I&#8217;ll tell you the difference between <em>preg_replace</em> and <em>preg_replace_callback</em> later. The first parameter is in all three cases the pattern to search for, the third is the string to search and replace. The second parameter is the replacement string (or callback function that returns the replacement string in the last case).</p>
<p style="text-align: justify;">Every regexp that is passed to one of those functions is enclosed within quotes. And I do not mean standard PHP string quotes now. These are of course also necessary, but also regexp string inside them needs to be enclosed within quotes. I use single quotes. And because single quotes have that special meaning, if we need to put a single quote inside a regexp, we need to put a backslash in front of it. And not only in front of a single quote, but in front of every character that has a special meaning for regexp (like <em>.</em>,<em>?</em>, …) if we want to suppress this meaning. But backslashes have similar special meaning in PHP strings, too. And because any regexp as a PHP function argument is a string, we need to put another backslash in front of every backslash in this string. That&#8217;s the reason why you can see so many backslashes <img src='https://www.moyablog.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . So now you shouldn&#8217;t be confused.</p>
<p style="text-align: justify;">So here is the meaning of some parts of regexps that we will use: (commented lines contain description)</p>
<p>$0 denotes the whole matched expression.</p>
<pre name="code" class="php:nocontrols:nogutter">$0</pre>
<p>If we enclose some parts of regexp within (), we create subexpressions. They are also called groups.</p>
<pre name="code" class="php:nocontrols:nogutter">(subregexp1)(subregexp2)restofregexp(endofregexp)</pre>
<p>We can then access these subexpressions using a dollar sign and the particular number.</p>
<pre name="code" class="php:nocontrols:nogutter">$1$2$3</pre>
<p>The special case of groups are so called &#8220;lookarounds&#8221; &#8211; you can learn more about them for example<br />
from this tutorial <a href="http://www.regular-expressions.info/lookaround.html" title="Lookahead and Lookbehind Zero-Width Assertions">http://www.regular-expressions.info/lookaround.html</a>.</p>
<p>One special case of them is so-called &#8220;negative lookahead&#8221;, for example:</p>
<pre name="code" class="php:nocontrols:nogutter">(?!http)</pre>
<p>Previous regexp fragment denotes that it will not match expressions that contain http substring in given part of the whole expression.</p>
<p>And just for the sake of completeness (definitions mostly from wikipedia <img src='https://www.moyablog.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ):</p>
<pre name="code" class="php:nocontrols:nogutter">
. // matches any single character
[ ] // matches a single character that is contained within the brackets
[^ ] // matches a single character that is not contained within the brackets
^ // matches the starting position within the string
$ // matches the ending position of the string or the position just before a string-ending newline
* // matches the preceding element zero or more times
? // matches the preceding element zero or one time
+ // matches the preceding element one or more times
</pre>
<p style="text-align: justify;">Let&#8217;s return to the description of presented function. At the beginning of the function we trim relative URL for the case it has some leading white space (for example if we got it from element&#8217;s <em>href</em> attribute with leading space), but we can remove it, if we want to preserve potential white spaces (but then trim action has to be moved to all the conditions later in the function that compare strings with the beginning of relative URL). Then we check if passed URL is not an absolute URL (if it is, we skill all following steps and return it). Then removal of single dots follows. Then we use parse_url function to get parts of URL (host, scheme, etc.). </p>
<p style="text-align: justify;">Lines 16-22 resolve situations when URL begins with a series of double dots and forward slash (../, ../../, …). First we count number of these and according that number is then adjusted the base absolute URL by removing last <em>number</em> of directories from this URL. Lines 25-30 resolve a series of double dots and forward slash inside URL. The rest of function deals with remaining situations.</p>
<div>
<hr /></div>
<p style="text-align: justify;">The first situation dealt with the most frequent potential use &#8211; simply single URL conversion. But we might need a more complex task &#8211; to replace all relative URLs inside some text. There is of course no universal solution for these, as there is no way to determine what actually is a relative URL and what is not, unless it is somehow denoted. Such a case are URLs inside CSS styles enclosed within <em>url()</em> (or <em>url(&#8221;)</em> or<em>url(&#8220;&#8221;)</em>). For this task I wrote the function that use regular expressions more extensively. And I also used <em>preg_replace_callback</em> function, so now I will explain this function.</p>
<p style="text-align: justify;">It&#8217;s essentially the same as <em>preg_replace</em>, but it uses the callback function that returns replacement string. <em>$matches</em> are passed as an parameter. $matches[0] represents $0 and $matches[1] subexpression $1, $matches[2] subexpression $2 and so on. This function is used when we need to make some changes on the whole matched expression or matched subexpressions or when we want to take some information from them and according them built up the replacement string.</p>
<p style="text-align: justify;">The used callbacks were created with <em>create_function</em> function which has the definition of this callback function as a string parameter. Note that to access value from outside of it I used the global variable <em>$callBackAbsoluteURL</em>. You cannot use variables from outside the function that are not declared as <strong>global</strong>.</p>
<p>So here is the function that converts all relative URLs inside CSS content to their absolute URLs counterparts:</p>
<pre name="code" class="php">
function convertCSSRelativeURLsToCSSAbsoluteURLs($baseAbsoluteURL, $cssContent)
{
   $urlInfo = parse_url($baseAbsoluteURL);
   if ($urlInfo == false) return false;
   $urlBasePath = substr($urlInfo['path'], 0, strrpos($urlInfo['path'],"/"));
   $urlBase = $urlInfo['scheme'].'://'.$urlInfo['host'].$urlBasePath;
   $dirDepth = substr_count($urlInfo['path'], '/')-1;
   global $callBackAbsoluteURL;
   $callBackAbsoluteURL = $baseAbsoluteURL;         

   $singleDotsCallback = create_function('$matches',
   '
     while (strpos($matches[0], "/./") !== false)
     {
        $matches[0]=str_replace("/./","/",$matches[0]);
     }
     if (substr($matches[2], 0, 2) === "./")
     {
        $matches[2] = substr($matches[2], 2);
        return $matches[1].$matches[2];
     }
     else return $matches[0];
   ');

   $doubleDotsCallback = create_function('$matches',
   '
     global $callBackAbsoluteURL;
     $baseAbsoluteURL=$callBackAbsoluteURL;
     $urlInfo = parse_url($baseAbsoluteURL);
     if ($urlInfo==false) return false;
     $urlBasePath = substr($urlInfo["path"], 0, strrpos($urlInfo["path"],"/"));
     $dirDepth=substr_count($urlInfo["path"], "/")-1;
     $dirDepthRel=substr_count($matches[2], "../");

     for ($i=0; $i&lt;$dirDepthRel; $i++)
     {
        $urlBasePath = substr($urlBasePath, 0, strrpos($urlBasePath,"/"));
     }

     $urlBase = $urlInfo["scheme"]."://".$urlInfo["host"].$urlBasePath;
     $relativeURL=$urlBase."/".$matches[4];
     return $matches[1].$relativeURL;
   ');

   $cssContentAfterSingleDotCheck = preg_replace_callback
   (
    '\'(url\\(\s*[\\\'"]?\\s*)(.*?\\))\'',
    $singleDotsCallback, $cssContent
   );
   $cssContentAfterDoubleDotCheck = preg_replace_callback
   (
    '\'(url\\(\\s*[\\\'"]?\\s*)((\\.\\./)+)(?!\.\\./)(.*?\\))\'',
    $doubleDotsCallback, $cssContentAfterSingleDotCheck
   );
   do
   {
      $tempContent=$cssContentAfterDoubleDotCheck;
      $filteredCssContentAfterDoubleDotCheck = preg_filter
      (
       '\'(url\\(.*?)(([^/]*)/\\.\\./)(.*?\\))\'',
       '$1$4', $cssContentAfterDoubleDotCheck
      );
      if ($filteredCssContentAfterDoubleDotCheck != NULL) $cssContentAfterDoubleDotCheck= filteredCssContentAfterDoubleDotCheck;
   }
   while ($tempContent != $cssContentAfterDoubleDotCheck);
   $cssContentAfterMissingURISchemeCheck = preg_replace
   (
    '\'(url\\(\\s*[\\\'"]?\\s*)(//)(.*?\\))\'',
    '$1'.$urlInfo['scheme'].':$2$3', $cssContentAfterDoubleDotCheck
   );
   $cssContentAfterRootDirCheck = preg_replace
   (
    '\'(url\\(\\s*[\\\'"]?\\s*)(/)(.*?\\))\'',
    '$1'.$urlInfo['scheme'].'://'.$urlInfo['host'].'$2$3', $cssContentAfterMissingURISchemeCheck
   );
   $cssContentAfterNoSlashesRelativeURLCheck = preg_replace
   (
    '\'(url\\(\\s*[\\\'"]?\\s*)(((?!https?://).)*?\\))\'',
    '$1'.$urlBase.'/'.'$2', $cssContentAfterRootDirCheck
   );

   return $cssContentAfterNoSlashesRelativeURLCheck;
}
</pre>
<p style="text-align: justify;">And finally some examples:</p>
<pre name="code" class="php">
  $baseAbsoluteURL = "http://www.moya.sk/images/ble/";

  $relativeURL = "images/green.png";
  echo convertRelativeToAbsoluteURL($baseAbsoluteURL, $relativeURL);
  //Output: http://www.moya.sk/images/ble/images/green.png
  $relativeURL = "images/test/../green.png";
  echo convertRelativeToAbsoluteURL($baseAbsoluteURL, $relativeURL);
  //Output: http://www.moya.sk/images/ble/images/green.png
  $relativeURL = "/test/test/images/red.png";
  echo convertRelativeToAbsoluteURL($baseAbsoluteURL, $relativeURL);
  //Output: http://www.moya.sk/test/test/images/red.png
  $relativeURL = "/test/test/images./red.png";
  echo convertRelativeToAbsoluteURL($baseAbsoluteURL, $relativeURL);
  //Output: http://www.moya.sk/test/test/images./red.png
  $relativeURL = "//www.webpage.com/test/test/images/red.png";
  echo convertRelativeToAbsoluteURL($baseAbsoluteURL, $relativeURL);
  //Output: http://www.webpage.com/test/test/images/red.png
  $relativeURL = "//www.webpage.com/lll../..ddd/s../test/test/./images/red.png";
  echo convertRelativeToAbsoluteURL($baseAbsoluteURL, $relativeURL);
  //Output: http://www.webpage.com/lll../..ddd/s../test/test/images/red.png
  $relativeURL = "//www.webpage.com/././test/test/./../images/red.png";
  echo convertRelativeToAbsoluteURL($baseAbsoluteURL, $relativeURL);
  //Output: http://www.webpage.com/test/images/red.png
  $relativeURL = "./images/red.png";
  echo convertRelativeToAbsoluteURL($baseAbsoluteURL, $relativeURL);
  //Output: http://www.moya.sk/images/ble/images/red.png
  $relativeURL = "../../../../../../../test/green.png";
  echo convertRelativeToAbsoluteURL($baseAbsoluteURL, $relativeURL);
  //Output: http://www.moya.sk/test/green.png
  $relativeURL = "../test/green.png";
  echo convertRelativeToAbsoluteURL($baseAbsoluteURL, $relativeURL);
  //Output: http://www.moya.sk/images/test/green.png
  $relativeURL = "../test/hh/../green.png";
  echo convertRelativeToAbsoluteURL($baseAbsoluteURL, $relativeURL);
  //Output: http://www.moya.sk/images/test/green.png
  $relativeURL = ".././test/gsreen.png";
  echo convertRelativeToAbsoluteURL($baseAbsoluteURL, $relativeURL);
  //Output: http://www.moya.sk/images/test/gsreen.png
  $relativeURL = "   images/green.png   ";
  echo convertRelativeToAbsoluteURL($baseAbsoluteURL, $relativeURL);
  //Output: http://www.moya.sk/images/ble/images/green.png
  $relativeURL = " /images/green.png";
  echo convertRelativeToAbsoluteURL($baseAbsoluteURL, $relativeURL);
  //Output: http://www.moya.sk/images/green.png
  $relativeURL="http://www.moya.sk/images/ble/images/red.png";
  echo convertRelativeToAbsoluteURL($baseAbsoluteURL, $relativeURL);
  //Output: http://www.moya.sk/images/ble/images/red.png

 $testCSS=
  "
  #image1 {backround: url(images/green.png);}
  #image2 {backround: url(images/bla/../bla/green.png);}
  #image3 {backround: url(images/bla/././././././././bla/../green.png);}
  #image4 {backround: url(images/bla/bla/bla/../green.png);}
  #image5 {backround: url(images/bla/lop../bla/bla/.s./green.png);}
  #image6 {backround: url(images/green.png);}
  #image7 {backround: url(/test/test/images/red.png);}
  #image8 {backround: url('images/green.png');}
  #image9 {backround: url(' /test/test/images/red.png');}
  #image10 {backround: url('./images/red.png');}
  #image11 {backround: url(../test/ggreen.png);}
  #image12 {backround: url(../test/hh/../ggreen.png);}
  #image13 {backround: url('  ./images/red.png');}
  #image14 {backround: url(  ../.././test/green.png   );}
  #image15 {backround: url( '../../../test/test/images/green.png');}
  #image16 {backround: url( /test/test/images/red.png   );}
  #image17 {backround: url(' /test/test/images/red.png '  );}
  #image18 {backround: url(        ' /test/test/images/red.png '   );}"
  .
  '
  #image19 {backround: url("//www.webpage.com/././test/test/./../images/red.png");}
  #image20 {backround: url("//www.webpage.com/././test/test/../images/red.png");}
  #image21 {backround: url("//www.webpage.com/lll../..ddd/test/test/./images/red.png");}
  #image22 {backround: url("images/green.png");}
  #image23 {backround: url("../test/test/images/red.png");}
  #image24 {backround: url(   "  ./images/green.png " );}
  #image25 {backround: url(        " /test/test/images/red.png "   );}
  ';

  echo nl2br(convertCSSRelativeURLsToCSSAbsoluteURLs($baseAbsoluteURL, $testCSS));
  /*
  Output:
 #image1 {backround: url(http://www.moya.sk/images/ble/images/green.png);}
 #image2 {backround: url(http://www.moya.sk/images/ble/images/bla/green.png);}
 #image3 {backround: url(http://www.moya.sk/images/ble/images/bla/green.png);}
 #image4 {backround: url(http://www.moya.sk/images/ble/images/bla/bla/green.png);}
 #image5 {backround: url(http://www.moya.sk/images/ble/images/bla/lop../bla/bla/.s./green.png);}
 #image6 {backround: url(http://www.moya.sk/images/ble/images/green.png);}
 #image7 {backround: url(http://www.moya.sk/test/test/images/red.png);}
 #image8 {backround: url('http://www.moya.sk/images/ble/images/green.png');}
 #image9 {backround: url(' http://www.moya.sk/test/test/images/red.png');}
 #image10 {backround: url('http://www.moya.sk/images/ble/images/red.png');}
 #image11 {backround: url(http://www.moya.sk/images/test/ggreen.png);}
 #image12 {backround: url(http://www.moya.sk/images/test/ggreen.png);}
 #image13 {backround: url(' http://www.moya.sk/images/ble/images/red.png');}
 #image14 {backround: url( http://www.moya.sk/test/green.png );}
 #image15 {backround: url( 'http://www.moya.sk/test/test/images/green.png');}
 #image16 {backround: url( http://www.moya.sk/test/test/images/red.png );}
 #image17 {backround: url(' http://www.moya.sk/test/test/images/red.png ' );}
 #image18 {backround: url( ' http://www.moya.sk/test/test/images/red.png ' );}
 #image19 {backround: url("http://www.webpage.com/test/images/red.png");}
 #image20 {backround: url("http://www.webpage.com/test/images/red.png");}
 #image21 {backround: url("http://www.webpage.com/lll../..ddd/test/test/images/red.png");}
 #image22 {backround: url("http://www.moya.sk/images/ble/images/green.png");}
 #image23 {backround: url("http://www.moya.sk/images/test/test/images/red.png");}
 #image24 {backround: url( " http://www.moya.sk/images/ble/images/green.png " );}
 #image25 {backround: url( " http://www.moya.sk/test/test/images/red.png " );}
  */
</pre>
<p>You can download these functions <a href="http://www.moyablog.com/relative-to-absolute-url-php/">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.moyablog.com/2011/10/19/how-to-convert-relative-urls-to-absolute-urls-in-websites-using-php/feed/</wfw:commentRss>
		<slash:comments>11242</slash:comments>
		</item>
		<item>
		<title>Essential Windows commands tips &#8211; part 1</title>
		<link>https://www.moyablog.com/2011/10/14/essential-windows-commands-tips-part-1/</link>
		<comments>https://www.moyablog.com/2011/10/14/essential-windows-commands-tips-part-1/#comments</comments>
		<pubDate>Fri, 14 Oct 2011 15:39:52 +0000</pubDate>
		<dc:creator>MOYA</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[bat]]></category>
		<category><![CDATA[batch files]]></category>
		<category><![CDATA[cmd]]></category>
		<category><![CDATA[command line]]></category>
		<category><![CDATA[command prompt]]></category>

		<guid isPermaLink="false">http://www.moyablog.com/?p=105</guid>
		<description><![CDATA[<p style="text-align: justify">I decided to write a series about Windows commands targeted to less skilled users (there will be nothing new for the advanced Windows users, so if you belong to this group, you may skip this article )</p> <p style="text-align: justify">This series is not intended to be a complete tutorial, its intent is just [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify">I decided to write a series about Windows commands targeted to less skilled users (there will be nothing new for the advanced Windows users, so if you belong to this group, you may skip this article <img src='https://www.moyablog.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  )</p>
<p style="text-align: justify">This series is not intended to be a complete tutorial, its intent is just to show some of the most useful tricks. However, since as I already mentioned, it is targeted to rookies, so in this first part we will deal with the very basics &#8211; how to actually work with commands, command line and batch files in general.</p>
<p><span id="more-105"></span></p>
<p style="text-align: justify">There are two ways of using commands &#8211; you can use it in the command prompt (<em>cmd.exe</em> or in old versions of Windows <em>command.com</em>) or you can use it in batch files.</p>
<h3>Using commands in command prompt</h3>
<p style="text-align: justify">Command Prompt can be found in Accessories. The fastest way to run it in Windows 7 is to press <em>Start</em> and type <em>cmd</em> in the search bar and press <em>Enter</em>. In Windows XP, you can do the same, but instead of typing it in the search bar, you run <em>Start-&gt;Run</em>. Hopefully you are not fed up with mentioning these trivial tasks <img src='https://www.moyablog.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p style="text-align: justify">So assume that we have already started Command Prompt (CMD). We probably see the path of our user&#8217;s account root directory (or possibly other path, it&#8217;s not relevant now). There are 4 commands that I consider the most important and crucial to mention for people who are running CMD for the first time &#8211; <strong>cd</strong>, <strong>dir</strong>, <strong>help</strong> and <strong>more</strong>. After learning these four commands you can start using the command line relatively proficiently.</p>
<p style="text-align: justify">Type <strong>help</strong>. You will see a list of commands with their short description as an output. You will probably not see the complete list, but just the bottom of it. But you can use a scrollbar to see the upper part. However, sometimes an output of CMD commands might be so large that you cannot see the full output.</p>
<p style="text-align: justify">Let&#8217;s type <strong>tree</strong>. This will start outputting the whole structure of your directories. You can wait quite long to finish it, or you may stop it by pressing CTRL + C after a while. In any case (if you were not too fast <img src='https://www.moyablog.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ), if you try to scroll on the top of command line window, you will not see the beginning of the output. For these situation there is a command called <strong>more</strong>.</p>
<p style="text-align: justify">Now type <strong>tree | more</strong>. The outputting will now stop so you can see the beginning of the output. You can shift it by pressing <em>Enter</em> line by line or by pressing <em>Space</em> screen by screen. Press CTRL + C to stop it.</p>
<p style="text-align: justify">When you type <strong>help</strong> together with another command name, it will show you help for this particular command. Try <strong>help cd</strong> for example. The second or further typed word of command is called <em>argument</em> or <em>parameter</em>. Instead of typing <strong>help cd</strong> you can also write <strong>cd /?</strong>. Arguments that starts with a forward slash (or with a hyphen, but this is not the case of standard Windows commands) are also sometimes called <em>switches</em>.</p>
<p style="text-align: justify">Now you can see outputted help of <strong>cd</strong> command. It contains text description, examples and in the beginning the command syntax. Note that arguments are in [] brackets. It means that these arguments are optional. Try to read instructions from that <strong>help</strong> output. Also try <strong>help dir</strong>.</p>
<p style="text-align: justify">I have not yet explicitly mentioned what are the tasks of <strong>cd</strong> and <strong>dir</strong> commands, but you had probably noticed it in the output of <strong>help</strong> command. In short, <strong>cd</strong> changes current active directory and<strong> dir</strong> lists all files and folders in the current or specified directory.</p>
<p>Here are som usage examples (commented odd lines contain description, even lines contain actual command):</p>
<pre name="code" class="vb">
'show contents of the current directory
dir
'show contents of the current directory
dir .
'change the current directory to the parent directory
cd ..
'show contents of the parent directory
dir ..
'change directory to drive C root directory
cd C:\
'change directory to directory C:\Users
cd C:\Users
'change directory to directory C:\Program Files
cd "C:\Program Files"
'show contents of directory C:\Program Files
dir "C:\Program Files"
'change drive to D:\
D:
</pre>
<p style="text-align: justify">You probably noticed two things, if you were attentive. We used double quotes in the antepenultimate and the penultimate example. That&#8217;s because the path of the chosen directory included white space, but white space is a delimiter for arguments. If an argument includes white spaces, you have to put it inside double quotes. The last example contains just <em>D:</em> and this switches the current drive. In fact, you cannot change a directory with <strong>cd</strong> command to directory outside the current drive. Although you can show its contents with <strong>dir</strong> command.</p>
<p style="text-align: justify">The last thing I will mention in this section is how to select and copy text from the command line. It differs from usual Windows way. Right-click on the CMD window and choose <em>Select All</em>. Then press <em>Enter</em>. Now the complete visible output is in the clipboard and you can paste it for example into Notepad. If you want to select just the part of CMD output, right-click again, but this time choose <em>Mark</em>. Click anywhere in the window and move cursor to select area to be copied and then press <em>Enter</em>.</p>
<p style="text-align: justify">Well, that&#8217;s enough for now. You can close CMD by typing <strong>exit</strong>. I intended to include also the basics of using batch files, but I don&#8217;t want to make this article too long. So, wait for the next time <img src='https://www.moyablog.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . </p>
]]></content:encoded>
			<wfw:commentRss>https://www.moyablog.com/2011/10/14/essential-windows-commands-tips-part-1/feed/</wfw:commentRss>
		<slash:comments>8368</slash:comments>
		</item>
		<item>
		<title>Pepan Durak</title>
		<link>https://www.moyablog.com/2011/10/10/pepan-durak/</link>
		<comments>https://www.moyablog.com/2011/10/10/pepan-durak/#comments</comments>
		<pubDate>Mon, 10 Oct 2011 17:33:34 +0000</pubDate>
		<dc:creator>MOYA</dc:creator>
				<category><![CDATA[Our products]]></category>
		<category><![CDATA[card game]]></category>
		<category><![CDATA[cards]]></category>
		<category><![CDATA[Durak]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[LAN]]></category>
		<category><![CDATA[netplay]]></category>

		<guid isPermaLink="false">http://www.moyablog.com/?p=97</guid>
		<description><![CDATA[<p>Let me introduce MOYA&#8217;s new card game Pepan Durak. Pepan Durak is a variant of popular card game. While standard Russian Durak is played with a deck o 36 cards, Pepan Durak is based on variant that is played with 32 cards, which is count typical for German cards. It is a LAN game, it [...]]]></description>
			<content:encoded><![CDATA[<p>Let me introduce MOYA&#8217;s new card game Pepan Durak. Pepan Durak is a variant of popular card game. While standard Russian Durak is played with a deck o 36 cards, Pepan Durak is based on variant that is played with 32 cards, which is count typical for German cards. It is a LAN game, it can be played on LAN (physical or virtual such as Hamachi) network. For more information visit <a href="http://pepandurak.moya.sk/" title="Pepan Durak">game&#8217;s homesite</a>.</p>
<p><img src="http://pepandurak.moya.sk/images/s4.png" alt="Pepan Durak" width="600" height="588" style="max-width: 100%;" /></p>
<p>Hope you will enjoy the game!</p>
]]></content:encoded>
			<wfw:commentRss>https://www.moyablog.com/2011/10/10/pepan-durak/feed/</wfw:commentRss>
		<slash:comments>10380</slash:comments>
		</item>
		<item>
		<title>Inner/Outer XHTML &#8211; or how to get truly original source of element in JavaScript?</title>
		<link>https://www.moyablog.com/2011/10/06/innerouter-xhtml-or-how-to-get-truly-original-source-of-element-in-javascript/</link>
		<comments>https://www.moyablog.com/2011/10/06/innerouter-xhtml-or-how-to-get-truly-original-source-of-element-in-javascript/#comments</comments>
		<pubDate>Thu, 06 Oct 2011 09:44:41 +0000</pubDate>
		<dc:creator>MOYA</dc:creator>
				<category><![CDATA[Web development]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[element source]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[innerHTML]]></category>
		<category><![CDATA[innerXHTML]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[original source]]></category>
		<category><![CDATA[outerHTML]]></category>
		<category><![CDATA[outerXHTML]]></category>
		<category><![CDATA[page source]]></category>
		<category><![CDATA[XHTML]]></category>
		<category><![CDATA[XMLHttpRequest]]></category>

		<guid isPermaLink="false">http://www.moyablog.com/?p=19</guid>
		<description><![CDATA[<p style="text-align: justify">There are some ways to get the original source of any HTML element in JavaScript. And they work fine in most situations. However, there are situations where these ways are not really sufficient and I especially mean not cross-browser enough.</p> <p style="text-align: justify">innerHTML property is probably the most frequently used method, but it [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify">There are some ways to get the original source of any HTML element in JavaScript. And they work fine in most situations. However, there are situations where these ways are not really sufficient and I especially mean not cross-browser enough.</p>
<p style="text-align: justify"><strong>innerHTML</strong> property is probably the most frequently used method, but it has some well-known drawbacks. First of all, <strong>innerHTML </strong>property does not contain (X)HTML written by original author of (X)HTML page. Instead, it contains some sort of browser specific Document Object Model string representation. Especially in IE this representation is quite ugly (missing quotes, capital letters of tags, …). And thus we encounter another problem &#8211; content of <strong>innerHTML</strong> property differs in different browsers!</p>
<p style="text-align: justify">But why is this important that it differs? Should we care? Maybe, we should. There might be situations when we may need the same value of innerHTML property for all browsers. There are always some tricks to get around this need and make it in other way, or simply make different solutions for different browsers. But wouldn&#8217;t it be nice to have function that not only returns same content in all modern major browsers, but moreover returns exactly the content that was created by author of webpage? Getting truly original source code is in fact another thing that might be sometimes useful.</p>
<p><span id="more-19"></span></p>
<p style="text-align: justify">So let&#8217;s show how to do this. I have written such a function for you.</p>
<p style="text-align: justify">The means to accomplish the most important initial building block of this task is <strong>XMLHttpRequest</strong>. We need to get the original source code of the whole page. Here is the function:</p>
<pre name="code" class="javascript">
function originalPageSource()
{
	var httpRequest = new XMLHttpRequest();
	if (window.ActiveXObject)
		httpRequest = new ActiveXObject ("Microsoft.XMLHTTP");
	else if (window.XMLHttpRequest)
		httpRequest = new XMLHttpRequest();

	httpRequest.open('GET',document.location.href,false);
	httpRequest.send(null);
	if (httpRequest.status === 200)
	{
		return httpRequest.responseText;
	}
	else return false;
}
</pre>
<p style="text-align: justify">This first function will be contained within the main function called <strong>originalInnerXHTML</strong>. It takes two parameters. The first parameter <em>element</em> is the required (X)HTML element, of which HTML content we want to see. The first parameter <em>includeElement</em> is a boolean parameter and determines whether to include element itself in (X)HTML string. This is known as an <strong>outerHTML</strong> function or property, so I as well made <strong>originalOuterXHTML</strong> to not to be required to call function with two parameters for this task. So finally, here is the code or <strong>originalInnerXHTML</strong>:</p>
<pre name="code" class="javascript">
function originalInnerXHTML (element, includeElement)
{
var elementXHTML = originalPageSource();
var elementIndex = 0;
var elementNodeName = element.nodeName;
var elements=document.getElementsByTagName(elementNodeName);

for (var i = 0; i &lt; elements.length; i++)
{
	if (element === elements[i])
	{
		 elementIndex=i;
		 break;
	}
}
openingElementRegExp = new RegExp("&lt;"+elementNodeName, "i");
closingElementRegExp = new RegExp("&lt;/"+elementNodeName, "i");
for(var i=0; i &lt;= elementIndex; i++)
{
	elementXHTML=elementXHTML.substring
	(
		elementXHTML.search(openingElementRegExp)+1
	);
}

elementXHTML="&lt;"+elementXHTML;
if
(
	element.hasChildNodes() == false &#038;&#038;
	(elementXHTML.indexOf("/") &lt; elementXHTML.indexOf("&gt;") ||
	elementXHTML.search(closingElementRegExp)==-1)
)
{
	if (includeElement)
	{
		elementXHTML=elementXHTML.substring(0, elementXHTML.indexOf("&gt;")+1);
		return elementXHTML;
	}
	else return "";
}
elementXHTMLCopy=elementXHTML;

while
(
	elementXHTMLCopy.search(new RegExp(openingElementRegExp))
	&lt; elementXHTMLCopy.search(new RegExp(closingElementRegExp))
)
{
	if (elementXHTMLCopy.search(openingElementRegExp)!=-1)
	{
		elementXHTMLCopy=elementXHTMLCopy.substring
		(
			elementXHTMLCopy.search(openingElementRegExp)
		);
		elementXHTMLCopy="&lt;"+elementXHTMLCopy;
		elementXHTMLCopy=elementXHTMLCopy.substring
		(
			elementXHTMLCopy.search(closingElementRegExp)
			+ elementNodeName.length+3
		);
		elementXHTMLCopy="&lt;"+elementNodeName+"&gt;"+elementXHTMLCopy;
	}
}

var endOffset = elementXHTMLCopy.length - elementXHTMLCopy.search(closingElementRegExp);
elementXHTML = elementXHTML.substring(0,elementXHTML.length - endOffset);
elementXHTML = elementXHTML+"&lt;/"+elementNodeName.toLowerCase()+">"

if (includeElement) return elementXHTML;
else
{
	elementXHTML=elementXHTML.substring
	(
		elementXHTML.indexOf("&gt;")+1,elementXHTML.lastIndexOf("&lt;")-1
	);
	return elementXHTML;
}

function originalPageSource ()
{
	var httpRequest = new XMLHttpRequest();
	if (window.ActiveXObject)
		httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
	else if (window.XMLHttpRequest)
		httpRequest = new XMLHttpRequest();
	httpRequest.open('GET',document.location.href,false);
	httpRequest.send(null);
	if (httpRequest.status === 200)
	{
		return httpRequest.responseText;
	}
	else return false;
}
}
</pre>
<p style="text-align: justify;">And finally source of originalOuterXHTML:</p>
<pre name="code" class="javascript">
function originalOuterXHTML(element)
{
	return originalInnerXHTML(element, true);
}
</pre>
<p style="text-align: justify;"><strong>Limitations</strong></p>
<p>The main limitation lies in the fact that this function returns only the original source code, so it cannot show potential javascript source code modifications. After the original source code is changed by script, we often simply have to rely only on internal browser object model representation… But after all, it is programmer&#8217;s responsibility in exactly which way his or her code is changed, so this can be mostly resolved. I believe that getting exact original source code might be useful in quite many situations.</p>
<p>You can download JS file with these functions <a href="http://www.moyablog.com/innerouter-xhtml/">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.moyablog.com/2011/10/06/innerouter-xhtml-or-how-to-get-truly-original-source-of-element-in-javascript/feed/</wfw:commentRss>
		<slash:comments>9061</slash:comments>
		</item>
		<item>
		<title>Welcome to my blog!</title>
		<link>https://www.moyablog.com/2011/10/06/welcome-to-my-blog/</link>
		<comments>https://www.moyablog.com/2011/10/06/welcome-to-my-blog/#comments</comments>
		<pubDate>Thu, 06 Oct 2011 06:50:29 +0000</pubDate>
		<dc:creator>MOYA</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.moyablog.com/?p=14</guid>
		<description><![CDATA[<p>So, this is the very first page of this blog. Where to begin?</p> <p>I&#8217;ll probably end up with simple wait and see! Useful articles from software world and articles about MOYA&#8217;s projects are coming soon. </p> ]]></description>
			<content:encoded><![CDATA[<p>So, this is the very first page of this blog. Where to begin?</p>
<p>I&#8217;ll probably end up with simple wait and see! Useful articles from software world and articles about MOYA&#8217;s projects are coming soon. <img src='https://www.moyablog.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>https://www.moyablog.com/2011/10/06/welcome-to-my-blog/feed/</wfw:commentRss>
		<slash:comments>10075</slash:comments>
		</item>
	</channel>
</rss>
