Geeklog Item Feed Adam Wilson Geeklog entries Thu, 18 Apr 2024 15:32:57 BST en-gb <![CDATA[Lucee task spooler]]> Thu, 18 Apr 2024 15:32:57 BST /WEB-INF/lucee/remote-client/ There are two folders 'closed' and 'open', I think it probably moves them from one folder to another as they fail. In my circumstance I just moved the .tsx files into another folder to get rid. This updates the counts in cfadmin and clears out the emails it was trying to send. I was breaching the web hosts email sending quota per hour and because there were so many emails queued the quota wasn't ever clearing. ]]> <![CDATA[There is a maximum length on mailto: links on windows.]]> Mon, 08 May 2023 13:43:59 BST <![CDATA[MariaDB / MySQL restricted words list]]> Thu, 29 Dec 2022 08:09:56 GMT You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ' comment_content Oddly there was only a column name there from a subquery. Turns out "row_number" had become a restricted. It turns out to be the name of a function so its probably best to avoid it. ROWNUM is in MariaDB 10.6 under some circumstances but not ROW_NUMBER It seems like ROW_NUMBER became reserved in Oracle MySQL in version 8.0.2 ]]> <![CDATA[Adding words to aspell dictionary command line]]> Fri, 14 Jan 2022 09:00:47 GMT git commit -m "Yarmouth"   Possible spelling errors found in commit message: Yarmouth obviously Yarmouth exists and is a word. To prevent me googling again how to add a word to the Aspell dictionary I will add this note to the log. echo "*Yarmouth\n#" | aspell -a @(#) International Ispell Version 3.1.20 (but really Aspell 0.60.8) This is on my Mac using OS X. ]]> <![CDATA[Copying ssl certificate from one server to another in plesk]]> Fri, 14 Jan 2022 09:00:47 GMT domain name > SSL/TLS Certificates and click unassign on the existing certificate first. Then you get the option to upload the pem file you downloaded from the other server. Hopefully in a couple of months time I will remember this when it happens again. ]]> <![CDATA[Clearing up code inserted after hack]]> Thu, 30 Jan 2020 16:02:57 GMT find /messedup/ -newermt "2020-01-19" ! -newermt 2020-01-21 -ls Finding modified files in two directories when you know that you have a good copy diff -br --exclude=".DS_Store" /messedup/ /good/copy/folder/ > difference.diff gives you a diff file and its child folders with all the differences ignoring whitespace changes if you just want the names of the files that don't match or where files only exist in directory or another. Ignoring OS X's .DS_store files. diff -qbr --exclude=".DS_Store" /messedup/ /good/copy/folder/ > difference-files.diff Find files in a directory that aren't pictures where everything should be a picture e.g. badfile.php find /messedup/images/ -type f -not -name "*.jpg" -not -name "*.jpeg" -not -name "*.JPG" -not -name "*.gif" -not -name "*.GIF" -not -name "*.png" ]]> <![CDATA[Building extensions with multiple versions of PHP]]> Mon, 29 Apr 2019 10:26:45 BST phpize, ./configure, make, make test, make install and then php wouldn't pick up the extension. I got errors like PHP Warning: PHP Startup: Unable to load dynamic library ... undefined symbol: spl_ce_Countable) Nice people at CWCS ( pointed out that I should have been using the cpanel version of PHP. Turns out I hadn't noticed that it had built itself against a very old version of PHP on the server rather than the version running on the command line. The successful process looked like this tar xzfv imagick-3.4.3.tgz cd imagick-3.4.3 /opt/cpanel/ea-php72/root/usr/bin/phpize ./configure --with-php-config=/opt/cpanel/ea-php72/root/usr/bin/php-config make make test make install ]]> <![CDATA[Processing Content Security Policy Logs]]> Tue, 25 Sep 2018 15:19:20 BST Header always set Content-Security-Policy-Report-Only "default-src .... When the browsers log the contraventions then send a json request to your end point you specify. I'm logging it to a file like DateTime, remote Ip, JSON, http_user_agent which makes it a bit more awkward to get the JSON in the report out but gives me enough information to be able to work out if I have a few repeat offenders or issues in a few browsers. The JSON isn't really ordered consistently so you can't easily scan through the file visually, sometimes the blocked-uri is at the start sometimes at the end for example. Also because they include the contravened directive in the report it can get to be a big block of text. So I'm doing something like awk -F, '{FS=", ";print $3}' csp.log > json-column.log to get the json out into a separate file with just the JSON column on each row. Then I'm doing a bit of Python to process the json in each row to extract the information I need for a simple summary import sys, json; import os fname="json-column.log" with open(fname) as f: for lineNumber, line in enumerate(f): data = json.loads(line); print data['csp-report']['blocked-uri'], ', ', data['csp-report']["violated-directive"]; Which output to a file gives me two columns blocked uri, violated-directive e.g:, font-src, frame-src so you can gauge how big a problem is by the number of rows when its sorted.

Understanding the Log

Some of the results are a bit difficult to understand, you think er whats that and look through the site code and find the blocked-uri doesn't exist on the site at all. the honey example above I think is someone having a plugin in their browser, that is then adding code to the page, there are quite a few rows like that. There are also more confusingly people with what seems to be malware in their browser redirecting links to other end points, I guess blocking those urls is doing the user of the browser a favour. The more confusing part is the odd stuff that you can't work out so easily then your googling to find out what comes from some url like If they have no viewable page there I'm assuming they are blockable and not worrying about them to much. Other entries are a bit more difficult to understand because the report json doesn't give you much of a clue where the blocked url is data or a blob or an extension data, img-src blob, script-src chrome-extension, font-src I know the site I'm looking at doesn't use data or blobs so I'm not that worried about blocking those, I'm just not sure at the moment if something is converting urls on the fly. When I look at the site in the browsers reporting the issues I don't see those violations in the browser console. Seems to be some debate about if CSP should affect extensions I guess people will shout when things stop working. ]]>
<![CDATA[Magento only stores shipping address firstname on Paypal Express orders]]> Wed, 25 Jul 2018 08:21:50 BST $shippingAddress->addData(array( 'firstname' => $data['SHIPTONAME'], )); Thats ok mostly but it causes some issues if your shipper requires lastname and firstname so can be a bit annoying. So you can change it if you need to. $nameParts = $this->splitNameIntoFirstAndLast($data['SHIPTONAME']); $shippingAddress->addData(array( 'firstname' => $nameParts['firstname'], 'lastname' => $nameParts['lastname'] )); I've added a function splitNameIntoFirstAndLast to that file to split the name eg Colin Smith to 'firstname' = Colin, 'lastname' = Smith. I can write a function given the customers of the store that had this problem ok working out about 98% of them. Probably because the customers mostly have European names. I think you would have to rethink this if your customers were from different places say Chinese or Vietnamese for example. The other file you have to change is app/code/core/mage/Paypal/Model/Express/Checkout.php which just comments out this line in the function returnFromPaypal which makes that lastname editable. $shippingAddress->setLastname(null); The function I wrote for splitting names looks like this. I think this is the bit you would want to change depending on your customers. I expect I'll tweak this over time. function splitNameIntoFirstAndLast($originalName){ $debug = true; /* if we have debug on we are testing and count failures * about 1.48% have empty last names in past 7308 with no last name in db */ if($debug){ global $count; } $titles = ['Dr','Dr.','Mrs','Mrs.','Mr','Mr.','Ms.', 'Ms', 'Miss.', 'Miss']; $name = trim($originalName); /* one bloke had name Colin Smith */ $name = str_replace(' ',' ', $name); /* if the name begins with a . like '. colin smith' */; $name = preg_replace('/^\. /', '', $name); /* if the name ends with a . like 'colin smith.' */; $name = preg_replace('/\.$/', '', $name); /* replace multiple whitespaces with one people like colin smith */ $name = preg_replace('/(\s){1,}/',' ', $name); if(strpos($name,',') !== false){ /* if they enter their name with commas in then its probably best to leave it, we could reverse it but its not always surname, firstname */ //$name = trim(implode(' ', array_reverse(explode(',', $name)))); } $foundTitle = $cofound = false; $nameParts = explode(' ', $name); /* colin smith C/O Some Company */ if(stripos($name,'C/O') !== false){ $nameParts = preg_split('/C\/O/i', $name); $nameParts[1] = substr($name, stripos($name,'C/O'),3).$nameParts[1]; $cofound = true; } $currentNamePartIndex = 0; $firstName = $nameParts[$currentNamePartIndex]; if(count($nameParts) > 2 && in_array($nameParts[0], $titles)){ $foundTitle = true; $currentNamePartIndex = 2; $firstName = $nameParts[1]; }else if(count($nameParts) > 2 && strlen($nameParts[$currentNamePartIndex]) == 1){ $currentNamePartIndex = 0; $firstName = ''; while(strlen($nameParts[$currentNamePartIndex]) == 1){ $firstName .= $nameParts[$currentNamePartIndex].' '; $currentNamePartIndex++; } $currentNamePartIndex-1; }else{ $currentNamePartIndex = $currentNamePartIndex+1; } $lastName = implode(' ',array_slice($nameParts,$currentNamePartIndex)); /* odds and sods */ /* camel case like ColinMcSomething */ if($lastName == '' && mb_strtoupper($firstName, 'utf-8') != $firstName){ $nameParts = preg_split('/(?=[A-Z])/', $firstName, -1, PREG_SPLIT_NO_EMPTY); if(count($nameParts) > 1){ $firstName = $nameParts[0]; $lastName = implode('', array_slice($nameParts,1)); } } /* */ if($lastName == '' && strpos($firstName,'@') !== false){ $nameParts = explode('@', $firstName); $firstName = $nameParts[0]; $lastName = implode('', array_slice($nameParts,1)); } /* colin no last name */ if($lastName == ''){ $lastName = 'Empty'; if($debug){ $count++; } } $parts = array($originalName, $firstName, $lastName); return array('firstname' => $parts[1], 'lastname' => $parts[2]); } This is on Magento The query I used to build a list of names from your database to test your name splitting function is SELECT DISTINCT(CONCAT('"',prefix_sales_flat_order_address.firstname,'",')) FROM prefix_sales_flat_order_address JOIN prefix_sales_flat_order on (prefix_sales_flat_order.shipping_address_id = prefix_sales_flat_order_address.entity_id AND prefix_sales_flat_order_address.address_type = 'shipping') or (prefix_sales_flat_order.billing_address_id = prefix_sales_flat_order_address.entity_id AND prefix_sales_flat_order_address.address_type = 'billing') WHERE prefix_sales_flat_order.created_at > '2017-01-01 00:00:00' AND lastname is null AND prefix_sales_flat_order_address.address_type = 'shipping'; I'm getting about 1.5% with 'Empty' as lastname. ]]> <![CDATA[Altering your hosts file]]> Wed, 25 Apr 2018 10:06:34 BST sudo cp /etc/hosts /etc/hosts-pre-editing then open the directory open /etc/ if your happy in vi or have a text editing program set up in your terminal go straight to editing it sudo vi /etc/hosts Then you can right click and open with your chosen code editor. You want to be editing this in a text editing program TextWrangler, BBEdit, TextMate or Vi rather than something like Word which will make more changes than you can see. The file will look something like below. You don't want to be editing any existing lines. ## # Host Database # # localhost is used to configure the loopback interface # when the system is booting.=C2=A0 Do not change this entry. ## localhost broadcasthost ::1 localhost fe80::1%lo0 localhost At the bottom of the file add a line like so Once you have made a change you probably want to refresh your DNS cache on the version of OS X I'm using (10.12) that is |sudo dscacheutil -flushcache;sudo killall -HUP mDNSResponder; | Then when you restart your browser you should be seeing the at rather than where ever its set to be in DNS globally. ]]> <![CDATA[XML stylesheet transformations in browsers on IE 9]]> Mon, 15 Jan 2018 11:14:34 GMT application/xlst+xml doesn't work on IE 9 but text/xml does the other seems to work fine in ie8 and 11 and firefox/chrome ]]> <![CDATA[Generating database diagram from .dot file]]> Mon, 15 Jan 2018 10:53:54 GMT fdp -Tpng > wordpress-database-diagram.png The information came from here and you get something that looks like this from a WordPress database. ]]> <![CDATA[WebRTC is interesting]]> Fri, 13 Jan 2017 15:21:48 GMT Strengths WebRTC is quite powerful, in essence you can conduct something like a Skype chat between multiple people just using standard web browsers without any plugins or add ons. So it has the potential to be very widely usable. You don't have to install a program on the users computer so you can skip operating system issues and you don't need a IT administrator to be involved if the users are in a school or university where installing programmes is restricted. Installing something on a users computer before the can take part in a chat is at best an inconvenience and a source of friction. Your saved the work of supporting multiple operating systems and developers who build the programmes. Its also the future so more and more devices and browsers should support it.


Fundamentally your restricted to the browser so integrating with the users computer outside of the browser box for something like screen sharing or sharing access to an application is cut off. You can create extensions or plugins to enable screen sharing. The user also has to allow their browser to share the video and sound from their system. You prompt them and they click to allow all or in some browsers just a single part sound or video. This shows another potential downside your restricted by browsers some what, you don't have to have the latest shiniest but you need something reasonably up to date. Google Chrome, Firefox work ok, and I think Edge. Unfortunately as you may have noticed those don't include Safari which restricts iPhone and iPad access. I've not found a why to this it just seems to be something Apple don't want to enable, yet. Some plugins exist that claim to enable WebRTC in the deficient browsers. whilst this seems negative I think more widespread support will emerge in the future. There is a browser support page here
Mostly communication is peer to peer with some negotiation STUN (Session Traversal Utilities for NAT) server if that doesn't work because of network topology then your forced to use a TURN server. This is not so shiny as it means you using the TURN server to relay message between chat members, this is a potential source of delays and processing demand on the TURN server your running. In my testing though I was able to use just the STUN server, I guess the TURN server would be more likely to need to used when one of the chat members was inside a large organisation. Its worth while considering the peer to per nature of the communication if you want to record chats as the data may not go through a central point where you can push it to a file. Handling between browsers varies slightly so you may want to use a framework that abstracts that away somewhat I used Simple WebRTC ( there are also services that offer WebRTC or parts as a service that you can than integrate into a wider application, if you want to find out more about to about the JavaScript its worth looking at the work of Muaz Khan at Ultimately I build a demo system in order to demonstrate feasibility and then stopped as there wasn't the budget at that point. Perhaps at some point that project will happen but its always useful to know what is and isn't feasible and what the limits of a technology are to use in others. ]]>
<![CDATA[Enabling DKIM to improve email delivery]]> Thu, 10 Nov 2016 15:40:01 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=selector1-colin-co-uk0k; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=w1YgdzreonJQDEXp57tSVab6RFSioTYfF4Ow92Cy6Xc=; b=on3S3MeOvI3UHa93jIPUxt23KEpYZrBK5BX3CGHyJxEa1og8zoX4RDU+WauGsjbNRoSPj84qTZUsUj8m22P3mGSo6u1Udh87vL0yIBtXN3SKVMCp9BSKOXC0d2M3QrUUAqOf/mAPs7ieqQQCUnx79q38bPk5L5kuz8t+NnOP+F0= but I found you can tell if an email is signed in gmail quite easily, if you look at a message then click the down arrow next to that shows you something like this from: Colin Example to: Adam date: 2 November 2016 at 16:58 subject: Re: wow is it really? Signed by: The signed by bit indicates that the email is signed by the server so you can be somewhat reassured that the email does come from the right server rather than a spammer. Found that most of my email addresses have DKIM set up without me doing anything which is nice. If you find yourself setting up DKIM or want to check its not setup wrong on your mail server you can also send a test email using that account to and they very nicely send you something back with a summary like this ========================================================== Summary of Results ========================================================== SPF check: pass DomainKeys check: pass DKIM check: fail SpamAssassin check: ham and lots of details which was very useful. I was setting it up on a old server where it wasn't just a tick box and it took me many attempts before I got it all to hang to together and the signing to validate successfully. (Canonicalization was what the last thing I was tripping up over in my opendkim.conf) DMARC Once you have SPF and DKIM setup you can then go on to set DMARC which gives you some reporting on whatis happening when your emails reach bigger mail hosts like googlemail and outlook. It also provides a way of you instructing the receiving mail server to what to do if the mail sent to them fails to pass DKIM or SPF checks. There is quite a lot to a DMARC record the best explanation I found was this one I ended up with something like this: TXT v=DMARC1; p=none; so I'm not telling receiving servers to do anything other than report to an email address. After a while and as my understanding increases I'll probably instruct it to do more possibly breaking actions (quarantine, reject) None of this really improves the security of email its still at some point being sent in plain text but it does give a receiving mail server another method of verifying that the email its received is legitimately from who it says it is. So in the end is making it more difficult for someone to send emails pretending to be from you. ]]> <![CDATA[Converting flv files to mp3 on CLI]]> Mon, 15 Aug 2016 15:27:07 BST #!/bin/bash # extract audio from flv files to mp3 files # using vlc app for file in /Directory/*.flv; do /Applications/ -I dummy $file --sout="#transcode{vcodec=dummy,acodec=mp3,ab=128,channels=2,samplerate=44100,scodec=none}:standard{mux=raw,access=file{overwrite},dst=\"$(echo "$file" | sed 's/\.[^\.]*$/.mp3/')\"}" vlc://quit; done; You end up with the Directory full of the original then converted version. aardvark.flv aardvark.mp3 cartilage.flv cartilage.mp3 This post was very helpful in working out the basis. There are a lot of arguments and I'm not an expert but my combination seems to work for the files I was working with. ]]> <![CDATA[Add Word to hunspell dictionary]]> Tue, 26 Jul 2016 09:07:27 BST git commit -m "Lowestoft is our most eastern port" --------------------------------------------------------------------- It looks like you have spell checking errors in your commit message: - You used =E2=80=9CLowestoft=E2=80=9D and hunspell suggested instead =E2= =80=9CLowest oft, Lowest-oft, Lowermost=E2=80=9D --------------------------------------------------------------------- So say you want to add Lowestoft Check if the word exists echo "Lowestoft" | hunspell -a @(#) International Ispell Version 3.2.06 (but really Hunspell 1.5.0) & Lowestoft 3 0: Lowest oft, Lowest-oft, Lowermost So Lowestoft doesn't exist in dictionary, as a comparison Yarmouth does echo "Yarmouth" | hunspell -a @(#) International Ispell Version 3.2.06 (but really Hunspell 1.5.0) * So lets add in Lowestoft echo -e "*Lowestoft\n#" | hunspell -a @(#) International Ispell Version 3.2.06 (but really Hunspell 1.5.0) Now check if it is there echo "Lowestoft" | hunspell -a @(#) International Ispell Version 3.2.06 (but really Hunspell 1.5.0) * Lowestoft is ok, even its not as famous as Yarmouth, and now its equally important in our dictionary. and now it gets suggested if you misspell it echo "Lowiestoft" | hunspell -a @(#) International Ispell Version 3.2.06 (but really Hunspell 1.5.0) & Lowiestoft 2 0: Lowestoft, Loftiness ]]> <![CDATA[Humbug for Mutation Testing]]> Tue, 17 May 2016 14:20:51 BST 'Humbug' by Pádraic Brady for the first time I was interested in how good bad it would show my tests to be First off you need to be able to run your phpunit tests without parameters as phpunit rather than phpunit Tests/ I had been running like that rather than specifying the test suite in my phpunit.xml ./Tests/ Before I added in the testsuite to the phpunit.xml I was getting the heading from humbug and then it was stopping and echoing out the help output from phpunit Then you need to check it runs ok and everything passes otherwise humbug stops Ivor:tools Ivor$ phpunit ............................................................... 63 / 248 ( 25%) ..............S................................................ 126 / 248 ( 50%) .................S................S............................ 189 / 248 ( 76%) .............................................S............. 248 / 248 (100%) Time: 34.08 seconds, Memory: 51.27Mb OK, but incomplete, skipped, or risky tests! Tests: 248, Assertions: 5606, Skipped: 4. Now trying humbug it may take some time ... Humbug on the above set of tests took 1.43 hours and there was a lot of output that made understanding it difficult. The output was quite useful though in that it showed weaknesses in my tests the --incremental flag is designed to speed up the test somewhat although in my circumstances it didn't make a large difference. To be honest at least at first you probably want to try this out on something smaller with just a few tests at first the output is easier to understand when your doing it on a smaller set of tests. You get an output file with diffs so you can have a look through and see how Humbug has twisted your code about. The one produced for the unit tests above was about 6000 lines. Then your left viewing the issues do they matter or are they false warnings. 1) \Humbug\Mutator\ReturnValue\This Diff on \adminLessonAccess::__construct() in /classes/adminLessonAccess.php: --- Original +++ New @@ @@ $this->db =3D dbConnection::get(); - return $this; + return null; } function listLessonsForAdminAccess(){ So my tests did not cover the constructor returning null rather than $this. 2) \Humbug\Mutator\Boolean\TrueValue Diff on \adminLessonAccess::deleteAllExpiredIds() in /classes/adminLessonAccess.php: --- Original +++ New @@ @@ } - return True; + return false; } Looking at the tests, my test covered that the things were deleted but not that the result should be true. Which isn't the end of the world but its a simple line to add an assertion that that should turn True; I think its a really useful tool in blowing a hole through how solid you thought your unit tests were according to code coverage stats and also in helping you improve existing unit tests and create better new ones.


I was using Humbug version 1.0.0-alpha1-18-gd102496 as a phar my humbug.dist.json looks like this { "source": { "directories": [ "../classes" ], "excludes": [ "../classes/PHPExcel" ] }, "timeout": 10, "logs": { "text": "humbuglog.txt" } }

Why do mutation testing at all

Pádraic probably answers that a lot better than I can in his article (currently down) if that link doesn't work try this. Put simply code coverage stats can be pretty overrated. They are good at showing how much of your code has tests but don't answer the other questions.
  • How good are those tests,
  • do they really test the code properly
  • are they just thin coverage filler written to achieve a coverage statistic.
  • are the tests strict or fluffy
  • are the tests redundant
These are some of the things you can get a better idea of with mutation testing. ]]>
<![CDATA[Static analysis of PHP code base using Phan]]> Tue, 26 Apr 2016 08:27:49 BST phan over a php codebase to try it out see what it produces. First ran least stringent which didn't produce much (possibly my code base is a magical unicorn) ./phan -p --minimum-severity=10 --quick --ignore-undeclared -f files.txt -o out.txt So then went to severest which produced noise ./phan -p --minimum-severity=0 --backward-compatibility-checks --dead-code-detection -f files.txt -o out.txt So then dialed back to ./phan --progress-bar --minimum-severity=0 --backward-compatibility-checks --file-list files.txt --ignore-undeclared --output out.txt There are possibly false warnings but it does give you an idea of places that might need consideration. Here I'm operating on a the result of a function that might return False on no results or an array of results on success. $siblings = $this->getSiblingsForAssessment($siblingGroups,$problemSetId); if($siblings){ $siblings = implode(',', $siblings); }else{ Which causes it to fuss as its thinking that $siblings is a (bool) ie True/False when it gets to $siblings = implode(',', $siblings); /classes/assessment.php:210 PhanParamSpecial1 Argument 2 (pieces) is bool but \implode() takes array when argument 1 is string /classes/assessment.php:210 PhanTypeMismatchArgumentInternal Argument 2 (glue) is bool but \implode() takes string Perhaps in a more functional world we wouldn't want to do something where the type of a value changes but in a php world where variables are mutable and type is flexible perhaps its not so bad. it can produce you more straight forwardly useful things like /classes/bookingChange.php:311 PhanNoopVariable Unused variable which was a pointless line $lessonStartDateTime; and warning you about optional arguments that are followed by non optional arguments in function calls PhanParamTooMany Call with 6 arg(s) to \className::functionName() which only takes 5 arg(s) so thats probably not intentional. Its probably useful as a way of reviewing code occasionally for smells and possible issues. I wouldn't worry about running as often as unit tests. Perhaps it would be useful as a way of viewing other peoples code or new code. Seems like its aimed athelping move a code base forward and stop it slipping back into old ‘bad’ habits. They have a tutorial for analysing sloppy code base and installation instructions. ]]> <![CDATA[Block user by IP Apache]]> Tue, 26 Apr 2016 08:13:01 BST <Limit POST> deny from </Limit> ErrorDocument 403 /forbidden.php The Error document pushes them off to the 'your forbidden' page that can then display them a message, log the request for later debugging etc. You can also use partial address and ranges like deny from 127.0.0. or deny from If you want to block multiple methods you can list them <Limit GET POST PUT DELETE > ]]> <![CDATA[Getting WordPress to actually publish posts on schedule]]> Fri, 08 Apr 2016 15:11:40 BST #!/bin/sh timestamp=$(date '+%Y-%m-%d %H:%M:%S'); curl=$(curl -s -o /dev/null -w "%{http_code}, %{url_effective}, %{time_total}\n"; echo $timestamp", "$curl >> ]]> <![CDATA[Finding unused css]]> Thu, 31 Mar 2016 09:12:46 BST <![CDATA[SRi - Sub Resource integrity]]> Thu, 31 Mar 2016 08:55:23 BST It is aimed at verifying that when a site is calling resources from a remote resource such as a CDN that the resources returned match that expected and the content have not been modified by some outside agent. For example the page loads css from but has no idea if is what it expects or has been modified by some malicious agent so all the text is pink. (possibly by militant my little pony fan girls) SRI allows link tag to include a hash of what the called resource should be <link rel="stylesheet" href="//" integrity="HASH M6kredJcxdsqkczBUjMLvqyHb1KHASH"> With HASHM6kredJcxdsqkczBUjMLvqyHb1KHASH being a hash of layout.css. This integrity attribute can be used by the user agent in this case a browser to avoid executing malicious or substituted code. If you think that the remote resource could be a script and you really don't want some random javascript injected in your page. Mozilla have a good explanation at Currently it seems only supported only in the browsers you would expect Chrome, Firefox and Opera ( ]]> <![CDATA[Things I wish I'd known when I picked up this Magento shop...]]> Tue, 28 Jul 2015 15:26:33 BST 1) Surprisingly some features don't work well, newsletters is probably best left alone, for example.
There may be fairly simple errors, for example: I upgraded the shop to the latest greatest in the 1.9 line thinking that those issues would be resolved they weren't. Mine were kind of minor, if your bought something with paypal buy now button the name of the customer would be blank on the 5 most recent orders. If you looked at the status of the order it would spray out html code rather than the link to the verify id. These aren't that bad and you can fix, reasonably easily. More to say that don't think everything will work just because its so widely used.
2) You need a beefy machine, this isn't going to work to well on shared hosting and its worth checking out how far you can push the PHP version beyond what versions they officially support. Newer versions of PHP being faster, generally. I pushed to .1 down from latest greatest version with some tweaking of the invoice creation code. Not got it onto php 7 (yet) though. The database is going to be a big and get bigger still so check your MySQL setup.
3) Its never going to be very fast, it wasn't really built to PHPs strengths. You are going to be working on coping with the core design decisions they made. Your back end options include enabling caching on as much as possible, including additional caching levels, I added a full page caching plugin Lesti which seems to work ok and reduced the time taken to actually chuckout the html to under 100ms. You will have to checkout that you have excluded the blocks that are customer specific. Magento have written some whitepapers about performance which are perhaps worth whizzing through. Including some configs that might work as starting points in Varnish, Nginx, PHP-FPM
4) Caching is also the root of problems if things don't appear or don't change on your updates after you 'update cache' in admin. Try emptying the cache directory rm -rf var/cache/
5) Front end performance may not be that fantastic either, check if combining the many and various css and js files speed things up for you and things still work.
6) If you amend a css file, the file name of the combined css will not change to do that you have to change the names of the files or do something like add a blank css file named cssBuster-{monthName}-{dayName}.css and add that to the layout.xml that you upload simultaneously.
7) You can update on the command line checkout ./mage list-upgrades
8) You can do reindexing from the command line php shell/indexer.php help I found reindexing periodically whether it needed it or not worthwhile. Having it update on save or manually is dependent on your evaluation and how understanding the shop keeper is of messages that may get flashed up whilst the are waiting for update. If your indexing is slow out check this plugin out. Depending on your config it skips, non visible and hidden url indexing which can greatly improves the speed, in my case it went from 50 seconds to 8 seconds
9) Log cleaning on the command line, log cleaning does keep the database size down I went from a database archive of something around 600mb to 260mb initially as no one had done it previously.
10) You probably want to enable as much logging as you can System > Developer > Log Settings The logs are quite noisy by default but you can grep out the noise and show the exceptional stuff. I have a rough bash script to process the system log for example.
11) Repeated blocked calls to /app/etc/config.xml in your logs are actually calls from Magento itself checking that that file is hidden, not an attacker. Although people do attack so you want to check your configuration, specifically to Magento files like LICENSE.* and *.sample probably don't need to be there. You also need to consider if you want to have the downloader online.
12) Checkout get.php it may be set to display errors, you don't want it to. It may be worth putting a die() in if you don't want to use it/ disagree with the concept of get.php.
13) If you can't login to the admin on a test server checkout the cookie domain see if it looks right. You can do something like this to make it blank in sql UPDATE prefix_core_config_data set value = '' where path = 'web/cookie/cookie_domain';
14) You can serve your static files from a CDN (and then toggle that according to if you are on https or not).
15) You set the timezone here System > Configuration > General > Locale Options > Timezone but Magento doesn't do British Summer time so you get times in GMT which may confuse you. It seems you can fiddle with it.
I'm still not sure I would recommend Magento to anyone, but I guess it works. ]]>
<![CDATA[Function (FunctionName) is not a valid method for this service]]> Thu, 09 Jul 2015 14:50:23 BST Fatal error: Uncaught SoapFault exception: [Client] Function (FunctionName) is not a valid method for this service in /file.php:118 Which was confusing me somewhat as when I did *__getFunctions* ( ) it would list out the function I was trying to use fine. It turned out that I had a soap wsdl cache enabled and that caused it to fail as once I'd switched that over in the php.ini to 0 it worked fine. In this instance I was using a local wsdl file so I didn't think to look at the caching for a long while. I'm guessing its an error cache writing/retrieval on the development machine so not typical. Just thought I'd post this here in case any body else has this mystery, and they can check this out as a possibility. The docs are at soap.wsdl_cache_enabled=1 became soap.wsdl_cache_enabled=0 I was using PHP 5.6.8 on OS X 10.8.5 ]]> <![CDATA[Mac internet connection dies after about a minute]]> Thu, 16 Apr 2015 08:36:53 BST ipv6 disabled. Then it worked dandy.
Mines a 2007 imac so it may be an older mac issue and different for you. I had changed router at some point and I think after that it failed, which makes it seem obvious that was the issue but because I only used it seldomly and often offline I hadn't noticed.
I had discounted the router being the issue as the connection worked for so many seconds before it died. I looked at error logs (useless), load - nothing and pulled other stuff apart. Seems dumb now but with no error it was guess work. Resetting Pram, updating operating systems, viruses, screen rewrite frequency and repair disk were "solutions" I came across whilst googleing
So if you have something like that happen to you try disabling ipv6 and see if that helps first, before you try more complicated solutions and get more frustrated. ]]>
<![CDATA[Generating .res files ICU version matters]]> Fri, 21 Nov 2014 11:05:02 GMT genrb –encoding utf-8 root.txt To generate on windows c:\program files\icu\bin\genrb.exe –encoding utf-8 root.txt To check it in isolation in php /* create resource bundle */ foreach (array("root") as $locale) { $r = ResourceBundle::create($locale, __DIR__); /* use a changed key to check it works */ echo $r["key-you-know-exists-in-root-txt"], "\n"; } ]]> <![CDATA[ssh using keys on CentOS (SE Linux) issues]]> Thu, 27 Feb 2014 11:08:29 GMT ls -laZ ~/.ssh will show you. I found mine was set wrong, if so, you can do something like chcon -R --type=ssh_home_t ~/.ssh Before I got it working I found it quite frustrating, tailing /var/secure/log was giving me entries like can't access /home/user/.ssh/authorized_keys. Even when I set logging to debug via sshd_config which wasn't very illuminating This doesn't seem to be mentioned in many places so mentioning here in case it helps anybody else. You can read more about security context/ security labels. ]]> <![CDATA[Incredible shrinking textarea I love you.]]> Thu, 16 Jan 2014 10:39:05 GMT The way I resolved it was to add in the html tag to disable compatibility mode or you can add in a similar http header X-UA-Compatible: IE=edge Pretty strange thing to happen I guess no one ever intended a textarea to do that, its pretty disconcerting having it shrink as you type. ]]> <![CDATA[freshclam: connect(): Permission denied]]> Fri, 20 Dec 2013 11:56:54 GMT ../cron.daily/freshclam: connect(): Permission denied So ssh'd on to the machine to run the script manually. First time the script ran same error, second time the script rang no error. Slightly confusing why would it not be able to get connect the first time and be fine after that? But then fail to connect the next day in the same way. After browsing the logs found out that it wasn't failing to connect to to download new virus definitions as I'd assumed. It was failing to tell Clamd that it had updated its virus definitions. Which explained it only failing the first time because the second or third time you ran the script it had already updated its definitions and so didn't need to to notify Clamd and therefore didn't fail. Once the Clamd was restarted the script ran without error. Guess it all goes to show as Tim says "assume makes and ass out of u and me". ]]> <![CDATA[Phar failed require caused by ioncube]]> Mon, 04 Nov 2013 08:23:58 GMT php -m | grep ion Once I disabled ioncube loader the phar ran just fine, on this server ioncube was loaded from from its own ini file /etc/php.d/00-ioncube-loader.ini Just in case anyone else has the same issue. ]]> <![CDATA[Why you want to avoid compatibility mode]]> Sat, 31 Aug 2013 15:14:45 BST <meta http-equiv="X-UA-Compatible" content="IE=edge"> You can read more Microsoft compatibility mode gubbins. * I maintain that Yuri Gagarin was pretty cool especially when you consider his rentry ]]> <![CDATA[apostrophes and htmlentities]]> Wed, 08 May 2013 07:27:43 BST & a p o s ; rather than & # 3 9 ; then move on this is dull. Pah & a p o s ; comes out as &apos in ie 7 and 8 stupid browser & # 3 9 ; is fine. I was pulling it in via ajax call which just complicates stuff, works fine when you get to Internet Explorer 9 I used & a p o s ; because it seemed more self documenting than & # 3 9; This old blog post explains more Apparently they are complying with a standard, if your really having trouble sleeping. I don't want to keep this stuff in my brain but hopefully this will be useful for someone else. So far today I've done html entities, 404 logs and pelmets: my thrilling life :) ]]> <![CDATA[FallbackResource Directive]]> Wed, 24 Apr 2013 14:37:55 BST Joshua Thijssen. He suggests using FallbackResource /index.php or whatever your controller is called, rather than more complex mod-rewrite rules to redirect all non existant files to the front controller on apache server. Just trying it on a test project and its working here, perhaps best for simpler project there don't seem to be lots of options but I should think a bit less error prone. You can read more in the apache docs . ]]> <![CDATA[Wonder if you can write Ruby in Chinese]]> Tue, 02 Apr 2013 15:45:59 BST "class name needs to begin with a CONSTANT so uppercase" class O目 def 时 puts "模棱两可"+"夏天" end end a = O目.new a.时 On a Mac at least you can name that file as "时". All those characters are just nonsense Pinyin characters. Google translates 模棱两可夏天 as "Ambiguous summer" :) , probably not entirely accurate but hopefully its not something too offensive. ( ]]> <![CDATA[Differences between MySQL Timestamp and Datetime columns]]> Wed, 13 Mar 2013 11:33:54 GMT "MySQL converts |TIMESTAMP| values from the current time zone to UTC for storage, and back from UTC to the current time zone for retrieval. (This does not occur for other types such as |DATETIME|.) ... ... If you store a |TIMESTAMP| value, and then change the time zone and retrieve the value, the retrieved value is different from the value you stored." That last bit is very important should be in very big letters probably. So for example on my desktop if I store the current time with the computer set to the Australia Sydney Timezone and then set the time zone on the computer back to GMT I get a time out of the TIMESTAMP column that doesn't match what I put in. This is either really great because the values adjusted to the current time zone auto magically or really bad because your not getting back what your put in to your database. DATETIME keeps the same time regardless of the servers change in time zone. As a demonstration if I create this table CREATE TABLE `test` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `ts` timestamp NULL DEFAULT NULL, `dt` datetime DEFAULT NULL, `desc` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; and enter 2013-03-03 03:03:03 In both the 'ts' and 'dt' of the columns whilst my computer is set to 'Australian Eastern Daylight Time'. When I reset my time zone to 'GMT' I get this back ts = 2013-03-02 16:03:03 dt = 2013-03-03 03:03:03 This most probably would never be an issue unless your MySQL server changes its time zone unnoticed (perhaps after a restart) at some point and then you might be glad you had chosen DATETIME. ]]> <![CDATA[Using Selenium to simulate random users]]> Thu, 07 Feb 2013 11:13:33 GMT <![CDATA[Add Wolfram Alpha as a search engine in Firefox]]> Fri, 14 Dec 2012 15:48:19 GMT github here as wolframalpha.xml and save it in (on a mac) to /Applications/ Not sure quite where that file location is on Windows/Linux but guess its a similar path within the program. <SearchPlugin xmlns=""> <ShortName>Wolfram Alpha</ShortName> <Description>Wolfram Alpha Search</Description> <InputEncoding>UTF-8</InputEncoding> <Image width="16" height="16"></Image> <Url type="application/x-suggestions+json" method="GET" template="{searchTerms}" /> <Url type="text/html" method="GET" template="{searchTerms}"> <Param name="i" value="{searchTerms}"/> </Url> <SearchForm></SearchForm> </SearchPlugin> ]]> <![CDATA[Oddity with Javascript name in WordPress]]> Fri, 14 Dec 2012 15:33:56 GMT script src="/js/jquery-1.7.1.js" type="text/javascript" But all that happened was I got the wordpress 404 page instead I thought hmm quite a lot to myself then drank some more tea and tried script src="/js/jquery171.js" type="text/javascript Which works I think its the dots and dashes in the filename which makes the difference. Also tried with jquery-171.js and jquery17.1.js which didn't work either but jquery_171.js did work. Seems an odd one so just just writing this in case it helps someone else. I was using Wordpress 3.4 ]]> <![CDATA[Convert measurements into newspaper speak]]> Mon, 15 Oct 2012 08:25:16 BST <![CDATA[getting file permissions in octal on OS X]]> Mon, 04 Jun 2012 19:00:13 BST stat -f '%A %a %N' * That works for me on OSX 10.5.8, but it does seem a little complex, I've just not found a simpler way yet. ]]> <![CDATA[installing node.js on OSX10.5.8]]> Mon, 23 Apr 2012 19:00:04 BST Macintosh:~ Toby$ node and got a big old error looking like so dyld: unknown required load command 0x80000022 Trace/BPT trap So then I thought I should go for the source code and do the .configure, make, make install thing. That didn't work either I ended up in the same place so then hit google. This guy was funny on OSX and actually some help although I thankfully I didn't need to go to the extremes he went to. Once I had downloaded the source code and changed into the expanded directory I just did this export PATH=/Developer/usr/bin:$PATH ISYSROOT="-isysroot /Developer/SDKs/MacOSX10.5.sdk" export LINKFLAGS=$ISYSROOT CXXFLAGS=$ISYSROOT CFLAGS=$ISYSROOT ./configure --prefix=$HOME --without-ssl make make install Now it seems to work dandy without ssl but this is just to try it out. I installed node-v0.6.15. ]]> <![CDATA[Trying out cloudflare]]> Tue, 10 Apr 2012 12:36:33 BST cloudflare I was quite interested to see how much difference it would make to the loading time of this site. I ran some simples tests before and after to see what difference it made along with a test of the same site on my local machine for comparison. I've bunged them in here if they are of any use to you. ------------------------------------------------------------------------ online at Dreamhost pre cloudfare ------------------------------------------------------------------------ Benchmarking (be patient).....done Server Software: Apache Server Hostname: Server Port: 80 Document Path: / Document Length: 12018 bytes Concurrency Level: 10 Time taken for tests: 8.023 seconds Complete requests: 100 Failed requests: 0 Write errors: 0 Total transferred: 1242420 bytes HTML transferred: 1218627 bytes Requests per second: 12.46 [#/sec] (mean) Time per request: 802.320 [ms] (mean) Time per request: 80.232 [ms] (mean, across all concurrent requests) Transfer rate: 151.22 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 174 182 4.7 181 202 Processing: 403 590 284.8 501 1608 Waiting: 216 346 289.9 263 1414 Total: 580 772 286.3 692 1792 Percentage of the requests served within a certain time (ms) 50% 692 66% 779 75% 792 80% 799 90% 848 95% 1748 98% 1779 99% 1792 100% 1792 (longest request) this is the site on my testing server on localhost ----------------------------------------------------------------------- On my mac Toby ----------------------------------------------------------------------- Macintosh:~ Toby$ ab -n 100 -c 10 This is ApacheBench, Version 2.3 Copyright 1996 Adam Twiss, Zeus Technology Ltd, Licensed to The Apache Software Foundation, Benchmarking (be patient).....done Server Software: Apache/2.2.21 Server Hostname: Server Port: 80 Document Path: / Document Length: 8655 bytes Concurrency Level: 10 Time taken for tests: 1.633 seconds Complete requests: 100 Failed requests: 0 Write errors: 0 Total transferred: 895700 bytes HTML transferred: 865500 bytes Requests per second: 61.23 [#/sec] (mean) Time per request: 163.327 [ms] (mean) Time per request: 16.333 [ms] (mean, across all concurrent requests) Transfer rate: 535.55 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 1.8 0 13 Processing: 64 159 33.2 160 253 Waiting: 64 153 30.6 154 241 Total: 65 159 33.0 160 254 Percentage of the requests served within a certain time (ms) 50% 160 66% 167 75% 172 80% 177 90% 204 95% 229 98% 242 99% 254 100% 254 (longest request) This the site once it was on cloudflare ----------------------------------------------------------------------------- On cloudflare ----------------------------------------------------------------------------- Last login: Sun Apr 8 11:17:09 on console Macintosh:~ Toby$ ab -n 100 -c 10 This is ApacheBench, Version 2.3 Copyright 1996 Adam Twiss, Zeus Technology Ltd, Licensed to The Apache Software Foundation, Benchmarking (be patient).....done Server Software: cloudflare-nginx Server Hostname: Server Port: 80 Document Path: / Document Length: 12020 bytes Concurrency Level: 10 Time taken for tests: 6.619 seconds Complete requests: 100 Failed requests: 0 Write errors: 0 Total transferred: 1265229 bytes HTML transferred: 1214025 bytes Requests per second: 15.11 [#/sec] (mean) Time per request: 661.933 [ms] (mean) Time per request: 66.193 [ms] (mean, across all concurrent requests) Transfer rate: 186.66 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 34 39 3.3 38 54 Processing: 255 604 519.0 349 2091 Waiting: 210 493 508.0 228 1973 Total: 293 643 520.2 390 2139 Percentage of the requests served within a certain time (ms) 50% 390 66% 456 75% 892 80% 1019 90% 1542 95% 2075 98% 2120 99% 2139 100% 2139 (longest request) I also ran some ping tests another site on same dreamhost hosting account no cloudflare ----------------------------------------------------------- round-trip min/avg/max/stddev = 173.442/173.796/174.234/0.329 ms this site with cloudflare ------------------------------------------------------------ round-trip min/avg/max/stddev = 31.984/33.248/34.279/0.721 ms Conclusion: So my ping time is better because its coming off a server in the UK now. The site generally doesn't seem that much faster but it was pretty fast to start with. Sue it will affect other sites more dramatically. To be honest this is really excessive for this site, its really simple and I don't pay for bandwidth anyway but it seems better to try stuff out on your own site rather than on a clients. Its free though so no bother to try out and if your on dreamhost you don't even have to mess with dns, only tick a box and let them do it. Some cloudflare oddities : if you add a subdomain they say they have added the root domain so you do add, they say thankyou for adding Ignore this. Also they see themselves as a security layer for your site. I wasn't particularly interested in that, there aren't comments on this site and its not really something i'm worried about hackers on. By default they block certain ip's with a captcha challenge. That seemed a bit unfriendly to me so I turned it off you can tweak this how you want. You can turn it for your admin area or some other bit. They also do email obfuscation If your not already doing that. There are a lot of different features including analytics. Its quite neat. ]]> <![CDATA[Easing equations]]> Mon, 09 Apr 2012 19:00:15 BST this site lists a whole bunch in actionscript code snippets so you can see what kind of thing your aiming at and get a preview of the what each term means. Along with the math behind each one. Was useful for me anyway sure you could use in Javascript too with some adaptions. ]]> <![CDATA[deploy script]]> Thu, 05 Apr 2012 19:00:05 BST #!/bin/sh # you could put the things to --exclude in a separate text file if they # get to lengthy # application_name="shiny.thing"; deploy_server=""; deploy_server_folder=""; ssh_user="XXXXXX"; script_location="./"; echo "Deploying '$application_name' to '$deploy_server' in folder '$deploy_server_folder'" echo "Reading source $script_location" rsync -avuz --delete --stats ./ $ssh_user@$deploy_server:$deploy_server_folder --exclude '.git' --exclude 'sessions' --exclude '' --exclude 'test.php' --exclude '.DS_Store' echo "Deployment successful and so much speedier than ftp/sftp" Guess I'll improve this quite a bit over next few weeks as I use it for a few more sites, perhaps also work out a way of not getting prompted for the SSH password each time too. Perhaps though prompting might be a good thing. ]]> <![CDATA[trying to figure out why wordpress doing so many database queries]]> Wed, 28 Mar 2012 19:00:20 BST <![CDATA[Grub boot loader bust]]> Wed, 28 Mar 2012 19:00:17 BST my geek opinions. Once I'd and ran 'boot-repair' it ran fine went through stages and fixed the boot loader and now his netbook seems to be working fine. Which is nice because I'm only a beginner to Ubuntu. ]]> <![CDATA[Poking Google charts]]> Thu, 08 Mar 2012 20:00:54 GMT google charts seems very neat and pretty simples. You just bung the code in the src attribute of an image tag and get back an image, just beware once you start poking it eats time. Here are some random chart api results.,FF8040,FFFF00,009900&chxt=x,y&chxl=0:|Woo!|1:|grr!|meh|shiny,20,20,20,20,0,0&chdl=First|Second|Third&chco=ff0000,00ff00,0000ff|1|000000|l|magic+monkey|moo+woo ]]> <![CDATA[Getting your authorship on your sites google search results]]> Wed, 29 Feb 2012 20:00:08 GMT <a href="" rel="author">Adam</a> just swap the '101603140027014722427' for whatever the number is in your profile url. I'm not sure how long it took but think I next looked a couple of weeks later and my google profile picture was appearing in the search results by then. Probably depends on how often you get crawled. Guess it would be good if you were guest blogging on a site. You can test that you have done it ok by visiting and typing in your url. ]]> <![CDATA[Removing profiles from web images on a mac 10.5.8]]> Thu, 09 Feb 2012 20:00:03 GMT background-color:#8063CE; so they should match but they were coming out slightly different colors. I think because the browser is using the profile when display the image. Neatly my mac came with a script that lets me remove the profile but its hidden at /Library/Scripts/ColorSync ]]> <![CDATA[browser size by percentage of users]]> Thu, 09 Feb 2012 20:00:03 GMT browser size tool available giving an estimate of what percentage of viewers will be see what proportion of your site. It seems a simple way of viewing it. You can put in your own url and see what percentage of people are missing the extremities of your site. I guess its only as reliable as their figures are but its a start. ]]> <![CDATA[installing tree command on os x]]> Wed, 25 Jan 2012 20:00:03 GMT blog post Which has now gone away, if you look on super user they have instructions From source like this ]]> <![CDATA[Behaviour Driven Development & Behat]]> Wed, 18 Jan 2012 20:00:07 GMT here. I'm not sure if BDD will fit in with how I work at the moment but I'm adding and to my list of things to poke and find out more about and see if it works for me. Adam ]]> <![CDATA[Quick view of the technologies that a site is built with]]> Wed, 11 Jan 2012 20:00:52 GMT Gives you server, info about analytics, js, doctype, cms etc. Bit quicker than perusing the sites source. ]]> <![CDATA[jsconsole]]> Tue, 10 Jan 2012 20:00:04 GMT <![CDATA[can't use 'name' as a form field in WordPress]]> Thu, 05 Jan 2012 20:00:03 GMT <![CDATA[reducing the number of post revisions in WordPress]]> Thu, 05 Jan 2012 20:00:03 GMT define('WP_POST_REVISIONS', 3); ]]> <![CDATA[User Agent Style sheets]]> Thu, 05 Jan 2012 20:00:03 GMT <![CDATA[jquery trim and ie 8]]> Fri, 30 Dec 2011 20:00:03 GMT this.value = this.value.trim(); Which worked fine in ff but pushed out error in IE8 its explained here because ie js String doesn't do String.trim So I swapped to this and this.value = $.trim(this.value); the docs for jquery trim are here ]]> <![CDATA[Hooray! my Firefox is up to date.]]> Wed, 28 Dec 2011 20:00:03 GMT <![CDATA[Setting wordpress language]]> Tue, 20 Dec 2011 20:00:12 GMT define('WPLANG', 'en-GB'); There is a list of language codes here if your unsure of yours. ]]> <![CDATA[You want to change all file names containing ? to a ]]> Mon, 31 Oct 2011 19:00:08 GMT for filename in *.jpg; do newname=`echo $filename | sed -e 's/?/a/g'`; mv "$filename" "$newname"; done ]]> <![CDATA[How to access query execution time in cf]]> Sun, 23 Oct 2011 19:00:03 BST #queryName.getMetaData().getExtendedMetaData().executionTime# #numberFormat(max(queryName.getMetaData().getExtendedMetaData().executionTime, 1)/1000, "0.000")# seconds more info ]]> <![CDATA[Changing hard drive on imac 7]]> Sun, 23 Oct 2011 19:00:03 BST Thanks to video it wasn't so bad but why did apple not just have panel on the back? Applestore 'genius' said the most awkward bit is the making sure there is no dust in between the glass and the screen. He is right I'm looking at the dust as I type. Apparently doesn't matter what type of drive you use just 3.5 but i ended up using 1TB seagate barracuda opened up mac and found old one was a 250gb seagate barracuda. Dandy ]]> <![CDATA[Creating an excel file from a query for non db people]]> Mon, 17 Oct 2011 19:00:18 BST <cfif isdefined("url.xls")> <cfheader name="Content-Disposition" value="inline; filename=TestimonialsForDuncan.xls"> <cfcontent type="application/vnd.msexcel"> <table border="1"> <cfoutput query="Testimonials"> <cfif Testimonials.IsFirst()> <tr> <cfloop array="#Testimonials.getColumnList()#" index="i"><td>#i#</td></cfloop> </tr> </cfif> <tr> <cfloop array="#Testimonials.getColumnList()#" index="i"><td>#Testimonials[i][currentRow]#</td></cfloop> </tr> </cfoutput> </table> <cfabort> </cfif ]]> <![CDATA[background gradient css]]> Sun, 09 Oct 2011 19:00:08 BST background: #a90329; /* Old browsers */ background: -moz-linear-gradient(top, #a90329 0%, #ed04c2 13%, #04ccd3 40%, #0cba03 76%, #6d0019 100%); /* FF3.6+ */ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#a90329), color-stop(13%,#ed04c2), color-stop(40%,#04ccd3), color-stop(76%,#0cba03), color-stop(100%,#6d0019)); /* Chrome,Safari4+ */ background: -webkit-linear-gradient(top, #a90329 0%,#ed04c2 13%,#04ccd3 40%,#0cba03 76%,#6d0019 100%); /* Chrome10+,Safari5.1+ */ background: -o-linear-gradient(top, #a90329 0%,#ed04c2 13%,#04ccd3 40%,#0cba03 76%,#6d0019 100%); /* Opera11.10+ */ background: -ms-linear-gradient(top, #a90329 0%,#ed04c2 13%,#04ccd3 40%,#0cba03 76%,#6d0019 100%); /* IE10+ */ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#a90329', endColorstr='#6d0019',GradientType=0 ); /* IE6-9 */ background: linear-gradient(top, #a90329 0%,#ed04c2 13%,#04ccd3 40%,#0cba03 76%,#6d0019 100%); /* W3C */ ]]> <![CDATA[coordinates for combined background images css]]> Sun, 09 Oct 2011 19:00:08 BST <![CDATA[Glype as proxy]]> Sun, 11 Sep 2011 07:00:17 BST <![CDATA[ExpiresByType mod_expires]]> Wed, 07 Sep 2011 19:00:03 BST ExpiresByType image/gif A7776000 didn't realise you could do like this ExpiresByType image/x-icon "access plus 9 month" its all here at ]]> <![CDATA[Making an submit element the right height in firefox]]> Wed, 24 Aug 2011 07:00:03 BST #submitElement::-moz-focus-inner {border:0;} stack overflow and another ]]> <![CDATA[htaccess info]]> Mon, 01 Aug 2011 07:00:11 BST |[T=MIME-type] and forbidden.html [F] and gone.html [G] all are new to me. Found that after looking into hardening wordpress here which has some usefull stuff for the non wordpress site as well. | ]]> <![CDATA[Talk on regular expressions]]> Sun, 24 Jul 2011 19:00:10 BST <![CDATA[Ternary operators in cf]]> Sun, 24 Jul 2011 19:00:10 BST ternary operator Go Ben! ]]> <![CDATA[Javascript Graphs YUI]]> Sun, 03 Jul 2011 19:00:03 BST <![CDATA[See all files in OS X finder]]> Fri, 20 May 2011 19:00:15 BST Olv:~ adam$ defaults write AppleShowAllFiles TRUE Olv:~ adam$ killall Finder I was on Mac OS X 10.5.8 ]]> <![CDATA[Learning prolog]]> Sun, 15 May 2011 19:00:10 BST and Learn Prolog Now Prologtastic ]]> <![CDATA[When is abstraction to much abstraction]]> Sun, 15 May 2011 19:00:10 BST LessCSS, SASS & CoffeeScript and I'm wondering just generally if that is the way to go? When does abstracting, make something simple more complicated. Should you be doing things in the simplest way possible. Is it introducing more possible points of failure? If you introduce these steps are you also increasing the understanding needed to edit something from just CSS to CSS + SASS? Perhaps I'm just confused post getting geoffed on Friday. ]]> <![CDATA[Stripping white space from file but preserving in code tags]]> Tue, 26 Apr 2011 07:00:08 BST /* strip out excess where not in code tags*/ /* all the white space with single space */ $data = preg_replace('/(?!(?:[^|[^>]+))(\s)/i'," ", trim($data)); /* all the double spaces */ $data = preg_replace("/(?!(?:[^|[^>]+))( ){2,}/"," ",$data); /* all the > < spaces with >< */ $data = preg_replace("/(?!(?:[^|[^>]+))(> ]]> <![CDATA[Division problems on 32bit OS]]> Mon, 18 Apr 2011 19:54:58 BST (7849431181 % 41) produces -1 which threw me then I read about it a little more if you want to tell if your php is running under 32bit OS try this: echo PHP_INT_MAX; // I get 2147483647 If your 32bit you get: 2147483647 If your 64bit like dreamhost servers are you get 9223372036854775807 That really confused me. ]]> <![CDATA[Moving your wordpress blog to a new domain name]]> Mon, 14 Mar 2011 07:00:09 GMT UPDATE wp_options SET option_value = replace(option_value, '', '') WHERE option_name = 'home' OR option_name = 'siteurl'; If its all new and has few plugins this is only one line but after a while it can get repetitive in the options Update your posts UPDATE wp_posts SET guid = replace(guid, '',''); Then you probably want to check the content of your posts for links and included image paths etc SELECT * FROM wp_posts WHERE post_content like '%' In an ideal world there won't be any hard coded url paths in post contents but unfortunately :) Drink tea! ]]> <![CDATA[Case sensitive fieldnames in cf]]> Thu, 10 Mar 2011 20:00:03 GMT Raymond Camden has solution go him ]]> <![CDATA[Learning awk]]> Sun, 30 Jan 2011 20:00:17 GMT <![CDATA[cfabort in cfscript]]> Fri, 28 Jan 2011 20:00:04 GMT <![CDATA[How to mess with web.config file properties]]> Thu, 27 Jan 2011 20:00:10 GMT <![CDATA[Cfquery returns null in query result as [empty string] when you cf dump it]]> Thu, 13 Jan 2011 20:00:12 GMT asc(field) Eq '0' when field is your db field to tell if is null or as craig says len(field) Eq '0' ]]> <![CDATA[in Cf 9 you can do IsNull()]]> Thu, 13 Jan 2011 20:00:12 GMT working with NULL values. but from a query you can't. ]]> <![CDATA[SQL joins explained with pictures]]> Tue, 11 Jan 2011 20:00:09 GMT visual explanation of SQL joins helped me find that my error wasn't anything to do with my joins ironically ]]> <![CDATA[CF_SQL_DECIMAL in cf]]> Tue, 04 Jan 2011 20:00:08 GMT <cfqueryparam value = "39.60" CFSQLType = "CF_SQL_DECIMAL" > so you need to do this <cfqueryparam value = "39.60" CFSQLType = "CF_SQL_DECIMAL" scale="2" > and then you get 39.60 which is what you wanted ]]> <![CDATA[Find your Dad factor]]> Tue, 04 Jan 2011 14:48:43 GMT #!/bin/sh Child=100; Grandchild=50; GreatGrandchild=25; Beard=30; echo "Hello, But are you a Dad if so find out your Dadness"; echo - "Enter ChildCount (1,2 etc) "; read ChildCount echo - "Enter GrandChildCount (1,2 etc) "; read GrandChildCount echo - "Enter GreatGrandChildCount (1,2 etc) "; read GreatGrandChildCount echo - "Do you have Have Beard (1,0)"; read BeardCount Dadness=$((( ( ($Child*$ChildCount)+($Grandchild*$GrandChildCount) )+( ($GreatGrandchild*$GreatGrandChildCount) )+( ($Beard*$BeardCount) ) ))); echo - "Your Dadness is: "$Dadness; Kept me quiet during wet lunchtime anyway. ]]> <![CDATA[Renaming files based on their modification date in bash]]> Fri, 31 Dec 2010 14:05:07 GMT #!/bin/sh ## # copies all files in folder to YYYYMMDD.extension from their modification time; # # @param folder where to look for files in and where the renamed files will end up # # @return renamed files in folder folder="test/" counter=0; for i in $folder* do counter=$[counter+1]; mon="" j=`stat -f %Sm "$i" | awk '{printf("%d-%s-%02d",$4,$1,$2)}'` #echo "$j"; ext=`echo ${i:(-4)} | tr '[:upper:]' '[:lower:]'`; #echo $ext; case `echo ${j:5:3}` in Jan) mon=01 ;; Feb) mon=02 ;; Mar) mon=03 ;; Apr) mon=04 ;; May) mon=05 ;; Jun) mon=06 ;; Jul) mon=07 ;; Aug) mon=08 ;; Sep) mon=09 ;; Oct) mon=10 ;; Nov) mon=11 ;; Dec) mon=12 ;; *) mon=ERR esac j=${j:0:4}$mon${j:9:2} echo "$i ->" $folder$j$ext; mv "$i" $folder$j$ext; done echo $counter" files in \""$folder"\" renamed"; ]]> <![CDATA[If you want to use location() in a cfscript tag in coldfusion]]> Fri, 24 Dec 2010 20:00:08 GMT location(url="page_to_relocate_to", addtoken="true|false", statuscode="404") rather than how it describes in cf documentation location(url="page_to_relocate_to", "true|false", "404") because that doesn't work. I couldn't comment on the cf docs because their form doesn't work for me ]]> <![CDATA[Bash Scripting Tutorial]]> Sun, 12 Dec 2010 20:00:11 GMT this helpful ]]> <![CDATA[An approach to writing better js]]> Wed, 17 Nov 2010 08:00:17 GMT programming to patterns ]]> <![CDATA[Woo!]]> Sat, 09 Oct 2010 07:00:05 BST <![CDATA[Starting with Git]]> Sun, 19 Sep 2010 17:22:58 BST this quite helpful. ]]> <![CDATA[Coldfusion variable names can't contain a - character]]> Wed, 18 Aug 2010 20:06:50 BST Coldfusion Variable Naming Rules ]]> <![CDATA[Sqlite is the best thing thing since sliced bread]]> Sun, 15 Aug 2010 15:56:04 BST SQLite you should find out about it, it is really very neat. It seems to me that many people use sledgehammer databases like SQL server which are inappropriate for often nutcracker situations. SQLite allows things to be kept simple. ]]>