Tvinga HTC Desire att uppdatera facebook profilbilder

HTC DesireHTC Sense har fördelen att den enkelt länkar ihop konton på telefonen med facebook konton, detta är väldigt smidigt då man får mer information direkt i telefonen som e-postadresser, födelsedatum och alternativa telefonnummer. Men bäst av allt är nog att den synkroniserar profilbilderna vilket gör det väldigt smidigt att se vem som ringer och att hålla koll på sin telefonbok.

Den är dock inte lika bra på att uppdatera dessa profilbilder, min profilbild har varit samma sedan i julas och känns inte riktigt lika aktuell längre nu. Så jag började leta efter någon möjlighet att uppdatera profilbilderna och det visade sig att det inte var riktigt lika enkelt som jag hoppades på. Men efter lite trail and error lyckades jag komma fram till att enklaste metoden är att ta bort facebook integrationen helt och sedan lägga tillbaka den igen.

Inställningar > Konton och synkronisering > Facebook for HTC Sense > Ta bort konto

Vänta sedan en liten stund och lägg tillbaka kontot igen och den tar nu en liten stund att uppdatera all profilbilder. Min största rädsla var dock att den skulle tappa alla länkningar jag gjort manuellt men den verkar behållt alla facebooklänkar helt intakta efter uppdateringen också.

Om någon vet hur man kan få HTC Sense att sköta detta automatiskt istället, t.ex. uppdatera facebook profilbilder en gång i veckan eller liknande så får ni gärna skicka en kommentar 🙂

Anpassad bekräftelse med hjälp av jQuery

jQuery Easy Confirm Dialog pluginIbland behöver man få bekräftat från besökaren att de verkligen vill utföra åtgärden, det sker i de flesta program genom en standarddialogruta som ber användaren bekräfta med Ja eller Nej. På webben är det inte riktigt lika enkelt, det går att använda den inbyggda javascript funktionen confirm(). Men en hemsidan idag innehåller oftast mycket ajax och dialogrutor,  att en standard popup ruta både bryter layouten och kan bli förvirrande.

När jag behövde en dialogruta för en kunds hemsida började jag leta efter ersättningar till denna standardfunktion. Eftersom vi använder oss utan jQuery för övrig funktionalitet kollade jag naturligtvis efter plugins till jQuery. Med de flesta lösningarna krävde callback funktioner eller var överdrivet krävande. Så jag bestämde mig för att utveckla mig egen plugin jQuery Easy Confirm Dialog, den är som vanligt även tillgänglig på github.

Fördelarna med Easy Confirm Dialog plugin är:

  • Den är väldigt enkelt att integrera, kräver ingen modifikation på övrig kod och inga callbacks
  • Fungerar både på vanliga länkar och jQuery events.
  • Anpassningsbart språk, Svenska och Engelska finns som standard

Allt som krävs är att man binder knapparna/länkarna till easyconfirm(), den tar sedan hand om alla events och utför enbart dessa ifall användaren godkänner.

Exempel på Easy Confirm Dialog plugin

<script type="text/javascript">
$(function() {
  $(".confirm").easyconfirm();
  $("a").click(function() {
    alert("You approved the action");
  });
});</script>
<a href="#" class="confirm">Testlink</a>

Nya iPhone 4 blev en flopp

Följde som många andra Apples WWDC under kvällen på MacWorld och väntade för att se vilka nyheter Apple hade att komma med. Till att börja med måste jag säga säga att MacWorld gjorde ett riktigt bra jobb att rapportera live från eventet. Som jag förstår det får ingen sända live från lokalen. Istället laddade de upp snapshots/bilder samt twittringar om eventet vilket var mycket underhållande att följa.

Jag är själv en inbiten Mac användare och både jag och flickvännen sitter på våra macbooks just nu, men när det kom till valet av mobiltelefon blev det en Desire, anledningarna var flera. Jag gillar öppenheten med Android och Desiren är en riktigt bra dato…. förlåt telefon 🙂

Men det som nu efteråt fått mig att reagera är citatet från Steve Jobs:

”biggest leap we’ve taken’ since first model”

Med detta refererar de till

Videochat
Hade jag även i min Sony Ericsson k810 med mer än 3 år på nacken nu. Jag använde det säkert 2-3 gånger i början innan jag tröttnade.

Multitasking
Borde ju vara en självklarhet, Android kör det utan problem.

Vad var nyheterna? Var det bara jag som hade väntat mig något mer? Jag menar egentligen inte att nya iPhone är dålig men besviken är nog rätt ord, och att de sedan försöker göra det till något så stort och nyskapande är bara löjligt.

Hur cachar man delar av sidan i php för att snabba upp sidvisningar

För ett nuvarande projekt hade jag behov av att cacha data, men vi använder oss av ett specialskrivet framework och ville inte implementera caching på hela webbplatsen. Istället ville jag ha möjlighet att cacha delar av resultatet för att snabba upp sidvisningen. Anledningen är att jag behöver vissa mycket statistik på startsidan, denna statistik uppdateras inte särskilt, och i det här fallet är det inte så viktigt att datan är helt aktuell.

De krav jag hade när jag började kolla in i problemet är

  • Skall fungera på delar av resultatet (inte spara hela webbplatsen)
  • Resultatet skall sparas till statiska html-filer
  • Resultatet skall skapas när det efterfrågas unikt för varje besökare
  • Så liten påverkan på övrig kod som möjligt

Jag började så klart med att söka runt efter färdiga lösningar och hittade då en tråd på stackoverflow (How do I implement a HTML cache for a PHP site?), de flesta svaren är helt färdiga template system med inbyggd caching men eftersom vi använder ett eget framework och i dagsläget inte har tid att införa detta var det inte aktuellt för mig. Andra möjligheter var att använda proxy cache eller lösningar som Memcache eller APC men webbplatsen skall installeras på ett vanligt webbhotell och jag letade egentligen efter en enklare lösning än dessa.

Istället fastnade jag för PHPs inbyggda funktion för output-buffering vilket gör det möjligt att spara outputdatan i minnet och skriva den till fil för att vid nästa sidvisning läsa den från filen istället.

ob_start();
echo 1+2;
$cache = ob_get_contents();
ob_end_clean();
echo $cache;

Så ser det ut i sin simplaste form, där $cache nu håller datan, i det här fallet "3", som skall sparas. Tjusningen är att den även sparar all output, html kod och allt annat som finns mellan ob_start() och ob_get_content(). För att göra detta så smidigt som möjligt stoppade jag in det i en egen class PartialCache, jag har laddat upp classen i sin helhet på github för den som är intresserad. Här kommer också en kort genomgång och huvudpunkterna. Koden tillhandahålls open source och ”as is”, den behöver säkerligen modifieras lite innan den fungerar för dig.

public function __construct($site, $key, $disable=false)
  {
    if (is_array($key)) {
      $key = implode($key,"_");
    }

    if ($disabled)
      {
	$this->filename = dirname(__FILE__) ."/../cache/". $site ."/". $key .".html";
	$this->site = $site;
	$this->key = $key;
      }
  }

Jag använder mig av mappstrukturen samt filnamnen för att spara cachad data till disk, $site blir mappen och $key filnamnet, har man flera värden man vill skicka med läggs dessa ihop med en linje.

public function is_cached()
  {
    $limit = 60*60*24;
    return file_exists($this->filename) && (time() - $limit) > filemtime($this->filename);
  }

För att kolla ifall datan finns i cachen kontrollerar jag enbart ifall filen finns på disk och i mitt fall att filen inte är mer än 1 dag gammal.

public function start()
  {
    if (!$this->is_cached()) {
      ob_start();
      return true;
    } else {
      return false;
    }
  }
  public function render()
  {

    if ($this->is_cached()) {

      $cache = file_get_contents($this->filename);
      echo $cache;
      echo '<div class="info-box">'
	       . sprintf($this->text,
	                 strftime("%Aen den %e %B kl %H:%M", filemtime($this->filename)))
	. sprintf($this->link, $this->site, $this->key)
	. '</div>';

    } else {
      $cache = ob_get_contents();
      ob_end_clean();

      echo $cache;

      $file = fopen($this->filename, 'w');

      if (is_writable($this->filename)) {
        fwrite($file, $cache);
        fclose($file);
      } else {
        echo '<div class="info-box">Kunde <strong>inte skapa cache</strong>, troligen felaktiga rättigheter på servern. Vänligen kontakta systemadministratören.</div>';
      }

    }
  }

Jag har sedan de två funktionerna start och render, som ifall det inte finns någon cache startar output-buffern och i render sparar denna till fil. Finns den redan i cache retunerar funktionen false vilket indikerar att koden inte behövs köras igen, istället läser render från fil och skriver ut denna. Exempel på hur koden kan användas

<?php
  $cache = new PartialCache("statistics", $userid);
  if ($cache->start()):
?>
<h1>Resultatet</h1>
<p><?php echo $result;<?></p>
<?php
  endif;
  $cache->render();
?>

Så gör man för att enkelt cacha delar av sitt resultat unikt för varje besökare.

Hello world!

Nu är jag inte bara webbutvecklare, jag är bloggare också :). Välkommen till mitt krypin, min förhoppnings med denna blogg är att kunna dela med mig av det jag gör. Vem är jag då? Jag är 25 år och har de senaste 5 åren drivit firman Pixel2 (eller Pixel Square om vi skall vara helt korrekta). Jag började som webbutvecklare och fotograf men har nu nästan uteslutande jobbat med webbutveckling och konsultarbete. Min passion ligger på användarvänlighet och sökmotorvänlighet och jag jobbar till stor del med webbstandarder. Jag har jobbat med allt från framtagning av design, användarvänlighets studier, sökmotoroptimering, html5 + css3,  javascript och jQuery, ASP.NET, php + wordpress/oscommerce och nu senaste även python + django (min egen favorit).

Jag har precis avslutat en tre årig utbildning på IT-Universitetet (Software Engineering and Management) vilket resulterade i ett ex-jobb tillsammans med Marcus Ljungbladvarianthantering i bilindustrin (finns tillgänglig i sin helhet för den som är intresserad). Vad framtiden håller är inte bestämt men till sommaren har jag bestämt mig att ta tag i några av alla de projekt jag har liggande. Det är av just den anledningen som bloggen skapades, en möjlighet att ta alla mina idéer och förverkliga dem, om du väljer att följa med på resan kommer du få ta del av allt från tankarna bakom besluten, små tips och trix samt genomgång av resultaten.

Jag finns även på