MongoDB ile Flörtleşme ve MongoLab ile Bulut Veritabanı

NoSQL vertiabanı motorları son yıllarda çok popülerleşti, çünkü yapısız olmalarından dolayı daha kolay mimari değişiklik yapabileceğiniz veri yapıları olduğu için tercih edilmeye başladı. Ölçeklenebilirlik de klasik sql veritabanlarının sınırlı ve geleneksel kaldığı konulardı.
NoSQL çıkışı kesinlikle modern bir çözüm olarak görülebilir.

İnternette bir çok karşılaştırma, performans analiz yazıları bulabilirsiniz sql ve nosql veritabanları hakkında. Ancak her yere uyan mükemmel bir çözüm yok. Benim gördüğüm kadarıyla, hibrid ve akıllıca kurgulanarak dengelenmiş ve dağıtılmış sistemler en yaygın kullanımlar. Yani bazı şeyleri nosql ile daha zor ve daha çok kodlama zamanı harcayarak yapabilir, bazı şeyleri de sql ile yönetemez ve yapamazsınız.

Daha teknik konulara giriyorsanız zaten bu yazıdan daha çoğuna ihtiyacınız var 🙂 Bu yazı daha çok mongo’ya giriş ve flörtleşme dönemi hakkında.

Eğer MongoDB’yi denemek istiyorsanız, mongodb sunucusunu bilgisayarınıza yüklemek zorunda değilsiniz. Kurulumu da çok zor değil fakat sadece denemek için sunucu kurulumu konfigurasyonu gibi şeylerle uğraşmak zorunda değilsiniz. Sadece istemci sürücülerini kurmanız yeterli. Bu konu hakkında mongodb dökümantasyonundaki http://docs.mongodb.org/ecosystem/drivers/php/ sayfasını inceleyebilirsiniz.

MongoLab adında bağımsız bir servis sayesinde ücretsiz bir mongo veritabanı oluşturabilir ve denemelerinizi onun üstünde yapabilirsiniz. MongoLab veritabanı ve kullanıcınızı oluşturduktan sonra açık erişim izni veriyor. Dolayısıyla php’den veya herhangi diğer bir ortamdan doğrudan erişebiliyorsunuz.

Tabi ki servisin amacı mongo denemek isteyen insanlara servis sunmak değil. MongoLab bulut veritabanı servisi. Veri dosyalarının saklanmasını istediğiniz alt servisi (Amazon, Rackspace, Windows Azure vs…), hatta yüzeysel de olsa bölge seçebiliyorsunuz (Amerika veya Avrupa veya uzak doğudaki bir veri merkezi şeklinde).

MongoLab 500mblık bir alanı ücretsiz sağlıyor. Diğer sınırlamalarını bilmiyorum fakat ufak projeleriniz için veya deneme yapmak için ideal. Eğer uygulamanız çok veri kullanmaya başlarsa küçük, büyük paketleri veya kurumsal hizmetlerinden faydalanabilirsiniz.

MongoLab ile tamamen php mongo eklentisi bağımlılığından da kurtularak doğrudan servisin basit REST apisini kullanabilir ve tek başına çalışan bir uygulama yazmanız da mümkün.

Konumuz mongo iken, birkaç php-mongo interaksiyonunu denediğim bir php dosyasının kodunu doğrudan vermek istiyorum.

İlk satırlarda göreceğiniz dsn’i mongolab’den edineceğiniz sunucu adresi ve portunu (tahminimce her kullanıcı için farklı olma durumu var), veritabanı kullanıcı adınız ve şifrenizi belirterek tek parça string şeklinde belirttiginiz takdirde bağlantı sağlayabileceksiniz.

Mongo, küçük uygulamalarda veri düzeni zorunluluğu olmadığı için kullanması çok keyifli, fakat verinizi dökümante etmeyi unutmayın. Yoksa neyin ne olduğunu unutur veya ipin ucunu kaçırarak karmaşık bir veri yığını elde edebilirsiniz günün sonunda.

MongoDB dökümantasyonunu inceleyerek indeksleme, sorgulama ve veri yönetimi nasıl yapılıyor fikir edinebilirsiniz. Ayrıca php manual’daki bazı SQL örneklerinin php ile mongo sınıfında nasıl yapıldığını gösteren bu sayfayı: http://php.net/manual/en/mongo.sqltomongo.php incelemekte fayda var.

MongoLab servisinin adresi https://mongolab.com

İşe yarayacak birkaç FQL ve Facebook API sorgu optimizasyonu

Facebook uygulaması geliştirmek veya varolan uygulamanıza facebook güzelliklerini entegre etmek bir çok dilde (javascript, php vs) sdk’lar yardımı ile çok kolaylaştı. Fakat standart dışı işler yapmaya başladığınızda veya uygulama zekanızda birden fazla facebook methodunu zincirleme kullandığınızda, standart methodların yapamayacağı şeylere ihtiyaç duyabilir veya uygulamanız ile facebook API arasındaki iletişimini optimize etme ihtiyacı duyabilirsiniz.

Örnegin facebook’u üye kayıdı için kullandınız ve üye kaydında üye bilgilerini, üyenin fotografının orijinal versiyonunu (yüksek çözünürlüklü versiyonunu) ve arkadaş listesini uygulamanızda kullanacaksınız. Bunlardan ikisini (kullanıcı bilgilerini isteme ve arkadaş listesini istemeyi) neredeyse tüm facebook sdk’lerindeki standart methodlarla yapabilirsiniz. Ancak profil fotografının orijinal boyutunu almak için birden fazla şey yapmanız gerekebilir, ayrıca ortada düzgün bir method yok bunun için. Biraz hack gibi de olsa bilinen bir yöntemle bunu elde etmeye çalışacağızö dökümanın iletleyen kısımlarında buna değineceğim.

Biliyorsunuz facebook FQL (Facebook Query Language) denilen bir çeşit SQL dili kullanıyor. Geliştirici dökümantasyonunda tablo listesini ve her tabloya ait veri yapısını bulabilirsiniz. Ayrıca hangi veri türüne erişebilmek için hangi izinlere sahip olmanız gerektiği de dökümantasyonda veriliyor: http://developers.facebook.com/docs/reference/fql/

FQL’in güzel kısmı, birkaç basit SQL yapısını destekliyor olması. Çok gelişmiş şeyler yapılamasa da basit sub querying ile birçok işi kolayca halletmeniz mümkün.

En basit iki örnek olan kullanıcı bilgisi ve arkadaş listesi elde etmek için şu iki FQL’i kullanabilirsiniz.

[code=sql]SELECT uid, username, email, name, sex, birthday_date, verified FROM user WHERE uid = me()[/code]

FQL’de * şeklinde tüm kolonları seçme veya herhangi bir alanı seçici olarak kullanama seçeneğiniz yok. İstediğiniz tüm alanları belirlemeniz gerek. Ayrıca "WHERE birthday_date < '1980'" gibi bir seçici yazamazsınız. Dökümantasyonda da belirtilen ve sadece taranabilir (indexable) olarak tanımlanmış alanları kullabilirsiniz. Bunlar id, username gibi genel seçiciler. Bu FQL size tek satırlık bir sonuç dizisinde, kullanıcı bilgisini istenen alanları verecektir. Gördüğünüz gibi secicide me() fonksiyonunu kullanarak giriş yapmış olan kullanıcıyı id'sini elde etmeye çalışmadan FQL'de kulanabiliyoruz. Ya da idsini bildiğiniz bir kullanıcı için bir veri isteginde bulunabilirsiniz. Ancak eğer istek yaptığınız kullanıcı, istenen tüm alanlara erişim için uygulamanıza izin vermediyse hata alacaksınız. Yani istek yaptığınız kullanıcının özel bilgilerini sorguluyorsanız, o facebook kullanıcısının, uygulamanızı kurarak gerekli izinleri vermiş olması şart. Arkadaş listesini almak için kullanacağımız FQL: [code=sql]SELECT uid, name, pic_square FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1 = me())[/code] Bu FQL aynı zamanda nasıl sub query kullanabileceğinizi gösteren bir örnek. İç sorguda giriş yapmış kullanıcının arkadaşlarının id listesini alıyoruz, sonra genel kullanıcı bilgisi sorgulayabildiğimiz tabloda (users) bu listeyi sorguluyoruz. Arkadaş listesinden alabileceğiniz veriler de sınırlı. Yani her bilgiyi sorgulayamıyoruz. Az önce bahsettiğim profil fotografının orijinal yanı büyük versiyonunu elde etme işi bir parça hack sayılabilir. Yani kabul edilen bir method değil, fakat işe yarayan ve kullanılan bir method. Kullanıcınızdan user_photos iznini aldığınızda kullanıcınızın tüm albümlerini ve fotograflarını okuma hakkina sahip oluyorsunuz. Aşağıdaki FQL'i kullanarak profil fotografının orijinal boyutuna ulaşabilirsiniz: [code=sql]SELECT src_big FROM photo WHERE pid IN (SELECT cover_pid FROM albüm WHERE owner = me() AND type = 'profile')[/code] İç sorguda albüm tablosundan "profile" türündeki tekil ve özel olan albümün (bu albüm, profil fotografları albümü) cover_pid yani cover fotografının id'sini sorguluyoruz. Bu bize son yüklenen profil fotografının idsini veriyor. Sonra da fotograflar tablosundan src_big yani büyük boyut (genelde orijinal boyutu saklıyor facebook bu alanda) adresini istiyoruz. ## Optimizasyon demiştik Kodunuzu FQL ile çalışır hale getirmek, 3 farklı isteği ayrı ayrı çağırmanızı değiştirmeyecektir. Yani işimiz burada bitmiyor eğer optimizasyon yapmaya çalışıyorsak. Eski API'de tek istekte birden fazla FQL sorgusu yapmanızı sağlayan bir method vardı, başka şekillerde aynı method halen facebook tarafından sağlanıyor. Bu method ile dizi şeklinde tüm sorgularınızı isteyebilir ve büyük bir nense şeklinde tüm sonuçları tek seferde alabilmenizi sağlıyor. Böylece, zincir istekleri tek isteğe indirip aynı zinciri facebook sunucularına delege etmiş olursunuz. Facebook genelde sizin 3 ayrı istek yapmanızdan çok daha hızlı şekilde istekleri sorgulayıp dönecektir. Facebook aynı methodu farklı şekillerde sunmaya devam ediyor. Fakat ben size en genel olan methodu önerecegim. İstekleriniz FQL olsun olmasın, birden fazla opengraph isteğini tek seferde isteyip cevap alabildiğiniz method batch requests olarak adlandırılıyor. Bu yazı daha çok FQL'ler üstüne olduğu için batch requests üstüne başka bir yazıda değineceğim. Batch Requests hakkında detaylı bilgiyi facebook dökümantasyonundaki ilgili sayfadan edinebilirsiniz: https://developers.facebook.com/docs/reference/api/batch/

Google Search API ile ajax arama

Eğer bir kaynak arıyorsanız, indexlerin güncelliği, genişliği gibi nedenlerden dolayı, diğer arama motorları yerine Google’ı tercih etmek, iyi bir karar olarak düşünülebilir. Yaptığınız Google aramalarını programatik olarak yapmak ve sonuçları herhangi bir şekilde kullanmanın sayısız örneği verilebilir.

Örneğin, sayfanıza site içi arama eklemek istiyorsunuz. Sayfanıza ait içeriği eğer Google zaten tarıyorsa, site içi aramanız aslında basit bir Google araması ile yapılabilir. Biliyorsunuz Google’da “site:mfyz.com” şeklinde arama yapılacak domaini filtreleyebiliyorsunuz. Dolayısıyla site içi aramanızı, herhangi bir algoritma yazmaya gerek kalmadan, hatta sadece tarayıcıda javascript ile yapabilirsiniz.

Google’un istemci altyapıları için sunduğu JSON tabanlı bir arama APIsi var. Bu api sayesinde normal bir Google araması yapabiliyorsunuz.

Bu API’yi basit bir HTTP isteği ile kullanabiliyorsunuz. Herhangi bir Google araması yapıyormuş gibi bir sorgu gönderip cevabını json olarak alıp işleyebiliyorsunuz.

http://ajax.googleapis.com/ajax/services/search/web?v=1.0

Aramanızı bu URL’e gerekli parametreleri ekleyerek yaptığınızda Google en fazla 8 sonuç verecek şekilde dönüyor.

Cevap olarak dönen JSON içeriği uzun olduğu için burada göstermeyeceğim. Ama birkaç parametreyle gelen sonuç kümesini kullanabilir, sayfalama ve sonuç boyutu gibi parametreler ile sayfalama yapabilirsiniz.

Asıl kullanacağınız sonuç değeri, arama sonuçlarının bulunduğu **response.responseData.results** sonuç kümesi olacaktır. Basit bir nesne dizisi olan bu değeri javascript ile ekrana doğrudan basabilir veya sunucu taraflı bir kod ile işleyebilirsiniz.

Google bu API ile tek istekte en fazla 8 sonuç döndürüyor. Nedenini kesin bir şekilde bilmiyorum fakat güvenlik nedeniyle olduğunu tahmin ediyorum. Eğer 8’den fazla sonuç göstermek istiyorsanız birden fazla api çağrısı yapmak zorundasınız veya istemci tarafında sayfalama yaparak sonuçları sayfalama ile gösterebilirsiniz.

Sayfalama için API çağırısında göndereceğiniz **start** parametresi, arama sonuçlarının başlangıç sırasını belirtiyor. Eğer belirtilmezse geçerli değeri 0 olacaktır. Bundan sonra 8, 16, 24… şeklinde ikinci, üçüncü sayfaya ait sonuçları, ek çağrı yaparak yükleyebilirsiniz.

Burada kontrol etmeniz gereken tek şey, toplam bulunan sonuç kümenizde yeterli sonuç olup olmamasıdır. Yani eğer kullanıcı son sayfada ise “Sonraki Sayfa” linkini göstermemeniz gerekir. Basit bir sayfalama için;

toplam sayfa sayısı = toplam sonuç sayısı / sayfa başına düşen sonuç sayısı

bölümünün üste yuvarlanması ile bulunur. Bunu Google size toplam bulunan sonuç sayısını tahmini şekilde söylüyor.

Sonuç kümesindeki **response.responseData.cursor.estimatedResultCount** parametresi size sayısal olarak tahmini sonuç sayısını söyleyecektir. Sayfa sayısını hesaplayarak gerekli sayfalama navigasyonunu oluşturabilirsiniz.

Örneği kodlayalım

Yazının başlarında verdiğim site içi arama örneğini javascript ile kodlayalım. Doğrudan tüm kodu verip açıklayacağım.

HTML tarafında ihtiyacınız olan iki ana parça, arama formu ve sonuçları listeleyeceğiniz bir tablo veya liste.

Javascript tarafını jQuery kullanarak yazarak HTTP çağrısını, JSON sonucunu işleme, html elemanlarını yönetme gibi birçok kısmı kolayca halledebilirsiniz.

İlk yapmamız gereken şey arama formundan arama sorgusunu yakalamak ve arama butonundaki tıklama hareketini yakalamak olacak. Bunun için butonun tıklama olayını yakalayıp text alanının içeriğini alıyoruz.

Google’un arama APIsini basit bir HTTP isteği ile kullanacağımızı söylemiştim, sonuç bir json nesnesi olduğu için jQuery’nin http istek yardımcı methodlarından **getJSON** methodunu kullanarak hem isteği yönetebilir hem de cevabı işleyebiliriz.

Yukarıdaki javascript methodu basit bir HTTP çağrısı yapıp gelen json cevabını işliyor. Basitçe bir liste elemanı (ul) içeriği oluşturuyoruz. Gelen sonuç dizisini bir HTML koduna dönüştürüyoruz. Methodun sonunda ise oluşturulan HTML kodunu liste elemanınımıza ekliyoruz.

Bu methodda gördüğünüzü ilk parametre, arama formundan gelen arama sorgusu, ikinci parametre ise, sayfalama için Google APIsine gönderilecek olan sonuç başlangıç indeksi. Bu sayede bu fonksiyonu tekrar çağırarak ikinci, üçüncü ve diğer sayfalardaki arama sonuçlarını yükletebiliyoruz. İlk arama yapılırken yani yukarıda ilk verdiğim javascript kodunda çağırılan arama methodu “0” başlangıç parametresi ile çağrılıyor.

Bu methodda dikkatinizi çekmiş olan bir nokta da arama parametresin sonuna “site:mfyz.com” eklemiş olmam. Sorguya eklenen bu kısım, yapılan aramanın sonuçlarında sadece o domain’deki sayfaları döndürmesini sağlayacaktır.

Yukarıdaki HTML çıktısını CSS ile işleyebilirsiniz veya arama formunu “ara” butonu ile değil eş zamanlı arama gibi her tuşa basıldığında belirli bir zaman aşımı ile girilen kelimeyi yakalayıp arama yapabilirsiniz.

Küçük projeleriniz için tüm e-posta stratejinizi mailchimp ile yapın

E-posta pazarlaması (e-mail marketing) günümüzün görmezden gelinemez bir parçası. Eğer kullanıcı kitlenizle doğru iletişim kurmak, onların ürününüze veya hizmetinize olan bağlılığını artırmak istiyorsanız, düzenli e-posta kampanyaları yapmanız, veya ilgilendikleri içerikleri, sitenize girmelerini beklemeden e-posta kutularına ulaştırabiliyor olmanız gerekiyor. Bu, aktif kullanıcı kitlesine sahip olabilmeniz için neredeyse zorunda olduğunuz bir iş.

Kullanıcılarınızla doğru e-posta iletişimi kurabilmek için öncelikle bir e-posta pazarlama stratejiniz olması şart. Yani bir kullanıcı sitenize üye olduğunda hangi aralıklarla ne gibi içerikler almalıysa bunu kurgulamanız gerekiyor ilk olarak. Burada dikkat etmeniz gereken tek konu, yaptığınız e-posta pazarlamasının kullanıcı onayı ve kontrolü dahilinde olması. Eğer kullanıcınız, sizden gelen epostaları almayı istemiyorsa basit bir şekilde listenizden çıkabilmeli veya hangi türde içerik almak istediklerini ayarlayabilmelidir. Aksi takdirde kullanıcılar, epostalarınızı spam olarak işaretlemeye başlayacak ve eposta servis sağlayıcıları, eposta sunucularınızın spam skorunu yükseltecek ve hatta belki kara listelere de düşmenize neden olacaktır.

Şimdi gelelim işin teknik tarafına. E-posta pazarlama günümüzde büyük bir sektör. Eğer bir dış bir servis kullanmazsanız, şöyle bir senaryo olası. Yeni bir sunucu aldınız, taze bir ip adresiniz var internette ve sitenizi, eposta sunucunuzu aynı sunucu üstünden yayın yapacak şekilde ayarladınız ve yayına geçtiniz. Eğer sunucunuz yeni ve az önce bahsettiğim e-posta adresine göre bir liste yönetim altyapısı kurmadıysanız işiniz çok zor. Çünkü bir süre sunucunuzun ip adresine ait ün’ünü arttırmaya, böylelikle spam kutuları yerine inbox’a düşmeye başlamanız, ve bir geçmişinizin olması gerekiyor. Ayrıca listelerinizi yönetecek bir yazılımı yazmanız da çok kolay olmayacaktır.

Eğer bir teknoloji startup’i değilseniz aynı zamanda eposta odaklı birçok pazarlama kampanyası yaparak milyonlarca kullanıcıya aktif olarak eposta gönderimi yapmıyorsanız kendi yazılımınızı yazmanızın hiç bir değeri olmayacaktır, ayrıca teknik olarak da bir çok ilkel özelliği yazılımınıza katmak için aylar hatta belki yıllar harcayabilirsiniz.

Bu noktada basitleştirilmiş e-posta pazarlama servisleri devreye giriyor ve bu konuda hizmet veren yüzlerce şirketten birini tercih ederek bir çok gelişmiş izleme, yönetim yapabilirsiniz.

Şimdi size bunlardan biri olan mailchimp’i nasıl kullanabileceğinizi kısaca anlatacağım.

Mailchimp, e-posta pazarlaması konusunda en eskilerden biri ve şu an kullandığım diğer birkaç servise göre teknik açıdan en gelişmişi diyebilirim. Hatta kullanım kolaylığı açısından da en iyisi tecrübelerime göre.

Bu siteyi düşnün. mfyz.com’un kullanıcı kitlesi binlerce kullanıcıdan oluşmuyor, ayrıca çok güçlü bir e-posta pazarlama stratejisine de sahip değil, ihtiyaç da duymuyor çoğu zaman. Ama bazı dönemlerde tüm kullanıcılara veya bellir bir alt kitleye (mesela son ay içinde üye olan üyelere, veya php dökümanlarını okumuş olan kullanıcılara) belirli bir mesaj iletilmesine ihtiyaç duyuyor. Ya da genel bir bülten gönderilmesi gerekebiliyor.

Bu örnek senaryo, herhangi bir internet sitesine veya teknolojiyle bağlantılı iş fikirlerinin neredeyse 90%’ina uyarlanabilir. Burada bahsettiğim, ufak kullanıcı kitlesine sahip siteler. Bunun gerçek bir site olmasına da gerek yok. Ufak bir e-posta grubu da olabilir. Atıyorum bir müzisyenin showlarını yaparken bir not defteriyle insanların e-postalarını toplayıp oluşturduğu bir bülten listesi bile olabilir, veya okulda bir sanat klübünün üyeleri olabilir. Örnekler çoğaltılabilir.

Böyle bir kullanıcı kitleniz varsa ve bu kitleye hızlı bir şekilde bir mesaj iletmek istediğinizde mailchimp size ücretsiz olarak fayda sağlayabilir. Sanırım 2,000 kullanıcıya kadar ve aylık 12,000 eposta yani tüm kullanıcı kitlenize 6 kere eposta atmanızı sağlayacak kadar aylık bir kota sunuyor. Eğer bu sınırları aşıyorsanız, e-posta pazarlama stratejinize göre aylık üyelik veya gönderilen e-posta başına ödeme yaparak çok ufak bütçelerle e-posta pazalamanızı devam ettirebilirsiniz.

## Mailchimp nasıl çalışıyor?
Mailchimp, eposta listeleri, kampanyalar, formlar ve şablonlar olarak çok güzel şekilde yönetimsel bölümlere ayrılmış. E-posta tasarımlarınızı şablonlarda, kullanıcı kitlenizi tek veya birden fazla listede, bu listelere üye olunabilmesi veya üyelikten çıkmak, üyelik ayarlarını değiştirebilmek gibi işlemleri yapabilmek için formlar tasarlamanızı sağlıyor. Hazırladığınız bir şablonu bir listeye veya bir alt listeye göndermeyi kampanya olarak tanımlıyor ve kampanyalarınızı istediğiniz zaman başlatabiliyor veya ölçümleyebiliyorsunuz.

Kullanıcınızı kendi kayıt sistemine aldığınız anda, isterseniz API aracılığıyla kullanıcı bilgisini mailchimp’deki listenize de kaydedebiliyorsunuz. Mailchimp istediğiniz kadar kullanıcı detayını saklayabiliyor.

## Sitenize e-posta bültenininiz için üyelik formu koymak
Sitenize bülten hazırlamak istiyorsunuz. Diyelim ki, mailchimp’de bir liste oluşturdunuz “Bulten” adında. Formlar bölümünde signup form düzenleyerek kullanıcıdan isteyeceğiniz bilgileri ekleyip çıkarabiliyorsunuz. Kullanıcınızdan isteyeceğiniz bilgi sayısı ne kadar az ise o kadar daha çok üyelik alacağınızı unutmayın. Bir e-posta pazarlaması için gereken tek şeyin e-posta adresi olduğu aşikar. Dolayısıyla formunuzu sadece e-posta alanı kalacak şekilde düzenliyoruz.

Liste detayı sayfasındayken üstteki menüden “For Your Website” menüsünde “Signup Form Embed Code” sayfasına tıkladığımızda farklı görünüm seçenekleriyle üyelik formuna ait koda erişebilirsiniz.


Eğer css, html ile uğraşıp kendi görünümünüze uyarlamak istiyorsanız “Naked form” seçeneğini seçip javascript ve css olmayan çıplak form html kodunu kopyalayabilirsiniz. Sitenize yerleştirdikten sonra kendi form element stillerinizi uygulayabilirsiniz.


Bu formu sitenizin yan kolonuna veya sayfa sonu bölgesine yerleştirerek her sayfadan erişilebilir hale getirebilir ve daha çok bülten üyeligi yakalayabilirsiniz.

Artık, genel bir kampanya hazırlayarak bir “Bulten” listesindeki tüm üyelere, sitenizdeki gelişmeler hakkında düzenli mesaj gönderebilirsiniz.

PHP SDK ile Facebook API hareketlerini izleme ve optimize etme yöntemleri

Eger php tabanlı bir facebook uygulamanız varsa facebook’u sadece kimlik doğrulama dışında kullanıyor olabilirsiniz. Çok basit bir uygulamada bile en azından düzenli yaptığınız facebook api çağrıları vardır. Basit bir örnek ile, kimlik doğrulama sonrası arkadaş listesini ekrana basan ve seçtiğiniz arkadaşınızın doğum tarihini kullanarak bir hesaplama yapan bir uygulamanız var diyelim (mesela: doğum günü takvimi uygulaması). Biliyorsunuz ki arkadaşlarınızın doğum tarihi bilgisini ancak ek bir izin ile sorgulayabilirsiniz. Dolayısıyla kullanıcınız, bir arkadaşını seçtiğinde, seçilen facebook kullanıcısı detaylarını sorgulamadan önce, uygulamanızı kullanan kullanıcıdan o izni alıp almadığınızı kontrol etmeniz gerekir.

Uygulamanızı gerekli kontrolleri yaparak hata vermeyecek şekilde hazırladınız diyelim. Performans problemleri yaşıyorsanız, önce performans probleminizin nereden kaynaklandığını tespit etmeniz gerekir. Gerekli veritabanı ve php kod optimizasyonu yapmanıza rağmen hala performans problemleri yaşıyorsanız problem yüksek ihtimalle sunucunuz ile facebook sunucuları arasındaki iletişimin uzun sürmesidir. Bunun da en büyük kaynağı facebook sdk’sının kaç çağrı yaptığı, bunların toplamda ne kadar zaman aldığı olacaktır ve bu konuda bir fikriniz yok diyelim.

Bu noktada ufak bir değişiklikle sunucunuz ile facebook sunucuları arasındaki trafiği monitöre edebilirsiniz. Bu gözlem, aslında her cağrıda yapmak zorunda olmadığınız ama bilmeden yapıyor olduğunuz veya geçici şekillerde ön bellekte saklayabileceğiniz bilgileri, kontrolleri gösterecektir size.

Şimdi ufak bir değişiklikle trafiği yakalayalım. Bunun için base_facebook.php dosyasında olan api methodunu:

aşağıdaki şekilde güncelliyoruz:

$facebookApiCalls = array();
public function api( /* polymorphic */)
{
$args = func_get_args();

$time_start = microtime(true);

if (is_array($args[0])) {
$result = $this->_restserver($args[0]);
} else {
$result = call_user_func_array(array($this, ‘_graph’), $args);
}

$time_end = microtime(true);
$time_elapsed = $time_end – $time_start;
$time_elapsed *= 1000; //convert to millisecs

if (isset($GLOBALS[‘facebookApiCalls’])) $GLOBALS[‘facebookApiCalls’][] = array(
‘duration’ => $time_elapsed,
‘args’ => $args,
);
return $result;
}

Yukarıdaki kodda yaptığımız değişiklik basitçe api methodu her cağrılışında, facebook sunucularına yapılan http isteğinin ne kadar sürdüğünü ölçüp global bir dizide toplamak. Bu şekilde sayfanızın sonunda ekrana $facebookApiCalls dizisini bir tablo şeklinde veya basitçe var_dump alarak kaç çağrı yapıldığını, yapılan cağrıların her sayfada tekrar edip etmediğini gözlemleyip eğer yapılabiliyorsa ön bellekte veya oturum değişkenlerinde tutularak sorgu tasarrufu yapılıp yapılamayacağına karar verebilirsiniz. Eğer sorgularınız çok zaman alıyorsa sunucu trafiğinizde optimizasyonlara gidebilirsiniz.

Bir çok amatör programcı, sdk methodlarını veya bilindik open graph methodlarını kullanarak sorgu yapıyor ve çoklu işlem yaparken ayrı ayrı sorgu yapıyorlar. Aslında facebook veri yapısını biraz anladıktan sonra FQL yazarak birden fazla sorguyu tek sorguda toplayıp önbellekleyebilir ve bu sayede çok büyük bir optimizasyon sağlayabilirsiniz.

Yukarıdaki doğum günü takvimi örneği için yapılabilecek optimizasyon senaryosu şöyle olabilir: uygulama, "arkadaşların doğum tarihi" iznini her halukarda gerektiriyorsa ilk sayfa açılışında kontrol edilerek kullanıcının bu izni vermesine zorlanabilir, bu sayede her arkadaş seçiminde ayrı ayrı kontrol yapılmak zorunda kalınmaz. İkinci bir optimizasyon, arkadaş listesinin önbelleklenmesi olabilir. Hatta doğum günleri de arkadaş listesiyle sorgulanarak tek oturumda sadece tek istek ile uygulamanızı çalıştırmış olursunuz.

Bu optimizasyonlar sadece uygulama hızı için değil, sunucu trafiğinizi azaltmak için de düşünmeniz gereken optimizasyonlardır.

OpenGraph’e giriş

OpenGraph nedir?

OpenGraph Facebook’un APIsi için oluşturduğu yeni bir API (Application Programming Interface: Uygulama geliştirme arayüzü) yapısıdır. Proje, genel bir yapıda hazırlandığı için belki standartlaşma ihtimali de var fakat şu an için sadece Facebook kullanıyor.

Neden OpenGraph?

Şu an için zaten sadece Facebook ile kullanabileceğiniz opengraph yapısı, aslında bir uygulama ortamı için özelleştirilebilir esnek bir api yapısı. Yani Facebook’un klasik RESTful API’sinde Facebook’daki bilgiye ulaşabiliyor ve yönetbiliyordunuz. Bunlar hala mevcut ama Facebook’un veri yapısı için tasarlanmış methodlar olduğu için facebook ortamındaki bir facebook uygulaması bu api kanalını kullanamıyordu. Yani Facebook veri yapısına bağımlıydı.

OpenGraph’ın çıkış noktası, internetteki herşeyi içerik olarak özetlemek. Yani adresi belli olan herşey bir içerik olarak kabul ediliyor. Bunu ise linkler ile adresliyor Facebook; mantıklı bir yaklaşım aynı zamanda. Yani her url’in bir içeriği sunduğu düşünülüyor, daha spesifik olarak bu içerikleri istediğiniz kadar parametre ile detaylandırabiliyorsunuz. Bu tanımlamaları yapaken html/xhtml içeriğinizde opengraph ön ekli parametreler kullanarak yapabiliyorsunuz. Facebook’un genel opengraph parametreleri sayfa yani içerik hakkında genel bir bilgi içeriyor.

Bunlardan birkaçı;
[code=text]
og:title sayfa başlığı
og:description sayfa tanımı
og:image sayfayı temsil eden görsel
og:media sayfa, bir medya sunuyorsa onun doğrudan adresi (video, ses vb)
[/code]

Bu etiketleri sayfanıza eklediğinizde, biri sayfanızın adresini facebook’da paylaştığı zaman o sayfaya ait içeriği temsil edecek görsel, medya içeriği, içerik tanımı gibi detayları facebook yakalayabiliyor.

Opengraph’ın asıl esnekliğini görebileceğiniz şey, içeriğinizi gerçekten tanımlayacak özel değerleri kendi oluşturacağınız etiketlerle belirleyebilmeniz. Bu yapı aslında sadece facebook için değil genel bir web yaklaşımı için tasarlanmış bir şey. Yani google da opengraph etiketlerini tarayarak sayfanız hakkında özel bir indeks oluşturabilir.

Örnegin bir araba modelinin detay sayfasını tanımlarken, sadece sayfa başlığı, açıklaması veya arabanın görseli o sayfadaki içerik hakkında yeterli bilgi vermeyebilir. Özel olarak arabanın üretim yılı, markası, yolcu kapasitesi, rengi gibi değerleri de belirleyebilirsiniz.

OpenGraph’ın çıkış amacı, Facebook kullanıcılarının aktivitelerini daha detaylı ve özel bir şekilde göstermek istemesi. Facebook ilk “like” butonunu genelleştirdi ve şu anda web’de bir çok sayfada like butonunu kullanıyor herkes. Eğer bir sayfayı beğenirseniz kullanıcı profilinizde “Mehmet, XYZ sayfasını beğendi” şeklinde görünüyor. Ama OpenGraph ile hedeflenen şey, bu kullanıcı aktivitelerini uygulama geliştiricilerine iyi bir yapı ile sunmak. Şu an bir uygulamayı kullandığınızda o uygulama, uygulama içinde yaptığınız aktiviteyi daha detaylı şekilde “Mehmet Ortakoy’de fotoğraf çekti” veya “Mehmet BMW M3 ve 4 diğer araba modeliyle test sürüşü yaptı” gibi çok daha detaylı bir kullanıcı aktivitesi yayınlayabiliyorsunuz.

Bunun için Facebook geliştirici arayüzlerinde önce OpenGraph nesnenizi tanımlamanız gerekiyor. OpenGraph’da her nesne bir web adresi demek ve bu web adreslerini o içeriği sağlayan sayfalar olarak düşünün. Bir diğer parça da “aktivite” tanımı. Yukarıdaki araba örneğinde, “araba” bir nesne, ve sayfamız bir araba detay sayfası, kullanıcı aktivitesi de “test sürüşü yapmak”. OpenGraph ile aktivite, nesne tanımı yapıp kullanıcı aktivitesi yayınlamakla ilgili başka bir yazı hazırlayacağım fakat burada açıklayabilmek için daha detaylı bir örnek vermem gerekiyordu.

Neden Facebook uygulamanızı OpenGraph’a geçirmelisiniz?

Şu an halihazırda bir Facebook uygulamanız var olabilir. Uygulamada yapılan aktiviteye ilgili bir içeriği veya aktiviteyi kullanıcının profilinde paylaşıyor olabilirsiniz. Muhtemelen paylaşımda bulunduğunuz içerik genel bir durum güncellemesi gibi görünüyor, genel bir link ile başlık, açıklama ve görsel içeriyor.

Facebook kullanıcı adına paylaştığınız bu içerikleri kısa, uzun, gruplanmış veya topluluğu özetleyecek şekilde şekillendiremez çünkü her girdiyi gruplayacak veya birbiriyle ilişkisini ortaya koyacak bir bağ yok. OpenGraph burada devreye giriyor ve Facebook, nesneler, aktiviteler veya aynı aktiviteyi yapan birden fazla arkadaşınızı tek haber olarak gösterebiliyor.

Yukarıdaki örneği devam ettirsem, benim dışımda 2 arkadaşınız daha “test sürüsü” yapmışsa facebook benim aktivitemi ve değer 2 arkadaşınızın aktivitesini size “Mehmet ve 2 arkadaşınız daha test sürüsü yaptı” olarak gösterebiliyor. Hatta eğer aktiviteniz anlık değil zaman alan bir aktivite ise bunu daha önceden tanımlanmış olan bir OpenGraph özelliği olan eylem uzunluğu ile belirtebiliyorsunuz. Örnegin Facebook, şu an halen devam eden ve aynı nesneyi (yani içeriği) kullanarak aynı eylemde buluan arkadaşlarınızı tek hikayede gösterebiliyor “Mehmet ve Betül şu an Indiana Jones izliyor” (eylem: izlemek, icerik/nesne: Indiana Jones). Gurplama, sadece birden fazla arkadaşınızın aynı eylemı yapması şeklinde olmak zorunda değil. Bir arkadaşınızın aynı türde eylemi farklı nesneler (içerikler) ile yapması da düşünülebilir. Bir önceki ekran görüntüsündeki gruplanmış hikaye, benim Songza uygulamasını kullanarak Johannes Brahms playlistini dinlememi gösteriyor. Fakat songza bu haberi bu şekilde kendisi gruplamıyor. Songza’da her dinlediğim şarkı için Songza OpenGraph ile hangi şarkıyı dinlediğimi facebook’a gönderiyor. Bu içerikler aynı türde içerikler olduğu için bu şekilde tek hikaye olarak görünmeye başlıyor. Bu içerikleri tek seferde dinlemiş olmak zorunda da değilim. Gerekli gruplamayı facebook yapıyor. Biz sadece içeriklerin türleri, birbirleri ile ilişkilerini bildiriyoruz facebook’a. Ekran görüntüsünde görebileceğiniz gibi bu playlist’i tek seferde dinlememe göre değil aynı zamanda bir tarih aralığındaki (ekran görüntüsündeki hikayenin alt kısmında Jul 10 – July 16 şeklinde 6 günlük bir zaman dilimi için) benzer aktivitemi gruplayarak göstreiyor Facebook.

Yukarıdaki faydalar Facebook ortamı için olan faydalar olarak görünebilir fakat, bu hikayelerin göründükleri yerler farkettiğinizden çok daha fazla. Normalde klasik paylaşımda bulunan uygulamanız, kullanıcının profilinde bir içerik paylaştığında o hikaye sadece o kullanıcının profilinde ve o kullanıcının arkadaşlarının ana haber akışında görünüyor. Çoğu zaman ana haber akışı sayfasında (news feed) görünemiyor çünkü yorum yapılan, otomatik olmayan gönderilmiş güncellemeler sizin hikayenizi önem sırasında gerilere itiyor ve çoğu zaman görünmez hale getiriyor.

Eğer OpenGraph’de bir hikaye yayınlarsanız hikayeniz, kullanıcı profilinde gruplanıyor, eğer 5 hikayeden fazla gönderim yapmışsanız bir kutu ile uygulama adınız ve kullanıcı aktivitesi görünümü değiştirilebilir bir şekilde kullanıcı profilinde görüntüleniyor.

Yukarıda, foursquare’de son 1 ayda kazandığım rozetleri gruplanmış bir şekilde görebiliyoruz. Bu gruplamayı yine facebook yapıyor. Facebook’un geliştirici panelinde, uygulama ayarlarında OpenGraph sekmesinde bu kutuları yani gruplanacak içerik/hikaye türlerini, gruplandıkları zaman ne şekilde gösterileceğini detaylı bir şekilde ayarlayabiliyorsunuz.

Bunun dışında facebook’a bildirilen her hikaye ayrı bir şekilde anlık olarak facebook anasayfasında (news feed) sağ tarafta olan “Ticker” alanında anlık olarak görünüyor ve arkadaşınız haber akışını okuyor olmak durumunda da değil. Bunun dışında eğer birden fazla arkadaşınız aynı aktiviteyi yapıyorsa o hikaye daha üst önem sıralarına çıkıyor. Yani içeriğiniz veya aksiyonunuz birden fazla kişinin yapmasıyla daha önemli hale geliyor.

OpenGraph’ın hikayelere tıklanarak içeriklere (yani sayfanıza) ziyareti arttırdığı bir gerçek. Bu konuda TechCrunch’da veya diğer teknoloji bloglarında spotify’ın ve pinterest’in OpenGraph ile ziyaret ve etkileşim oranlarını katladığını okuyabilirsiniz. Bu iki örnek şu an iki OpenGraph başarı hikayesi olarak verilebilir.

Hazırlayan: Mehmet Fatih YILDIZ

Facebook entegrasyonu

mfyz.com’da üye kavramının bir anlamı olmadığını baştan belirtmek gerek. Sadece sitede yazılanları kimin yazdığını adresleyebilmek ve basit bir denetleme mekanizmasına sahip olmak için bir üyelik sistemine sahip mfyz.com.

Şu an için tek avantaj tek tık ile üye olmak ve giriş yapabilmek olarak eklediğim facebook entegrasyonu için ileride yazdığınız yorumlara subscribe olabilme gibi ufak eklentiler yapmayı planlıyorum. Ama şu an için facebook entegrasyonu düzgün bir şekilde calışıyor diyebilirim.

Eğer üye iseniz henüz facebook butonlarını kullanmayın, yakında varolan hesaba bağlama özelliği eklenecek.

Hataları bildirirseniz sevinirim.

PHP siniflarinizi RESTful API’lere cevirin: Restler

Restler, multi-protocol ve acik kaynak kodlu, siniflarinizi otomatik olarak rest api’lere ceviren bir php kutuphanesi.

Cok ufak ve XML, JSON, Plist and AMF gibi populer tasinabilir veri formatlarini destekliyor ve neredeyse tum http methodlariyla calisiyor.

Eger iyi yapilandirilmis bir sinifiniz var ve icindeki butun public methodlar genellikle bagimsiz birer gorevi ifade ediyorsa bu kutuphaneyle, sinifinizi her yerden kullanilabilir hale getirebilirsiniz. Veya api uretmek icin ozel bir sinif hazirlayip bu kutuphane ile rest api’ye cevirebilirsiniz.

Restler

Sosyal siteler

Son 5 yil icinde sosyal networkler fcok hizli bir sekilde populerlesti, hatta facebook deve donusup google gibi bir lideri sallayacak konuma geldi. Bu detaylari yazmama gerek yok piyasada bunlari takip ettiginiz milyon tane blog var zaten. Ben isin web gelistiricileri tarafindaki gidisatini sizlerle paylasmak istiyorum.

Bu sosyallesen ve web 2.0 kavraminin gercekten oturdugunu hissetmemizi saglayan tek sey sitelerin yani web uygulamalarinin birbirleri ile cok guzel haberlesmeye baslamalaridir. Bunu bu kadar iyi anlamamizi saglayan orneklerden biri yine aslinda facebook. Tabi ki google veya yahoo servislerinde de bircok yontemle haberlesiyorduk fakat ortak bir dil/standart yoktu. Simdi ise her yer API doldu. Yani uygulamalar artik aralarinda en azindan bazi standartlara uyarak haberlesmeye basladilar. Bunun en buyuk ornegi oauth apileridir. Su an elinizi nereye atsaniz yakalayacaginiz sitelerin cogunun apisi var. Aslinda bu gelismeye cok olumlu bakiyorum ben. Cunku artik sitelerin verilerini kendilerine saklama gibi bir tavri yok.

Cok basit bir ornek vermem gerekirse, yillardir kullandigim delicious servisi yahoo tarafindan alindiktan sonra servisin yayin hayatini sonlandiracagi yazildi her yerde. Bir parca gercek de olabilir, onemli degil, olagan seyler bunlar. Ancak kullanici olarak ben yillarca tagledigim bookmarklarimi kaybetme tehlikesi sezdim. Bu gelisme bundan 10 sene once olsa oturup giden bookmarklarima dua etmekten baska secenegim olmazdi. Ya da tek tek oturup bookmarklarimi kopyalamaya calisirdim. Ama butun icerigi koruyacagim tartisma konusu olurdu.

Simdi ise, aninda birileri bir arac gelistirip, kullaniciya api erisim izni sorarak sizin bookmarklarinizi evernote veya baska formatlarda okunabilecek sekilde export etmenizi saglayabiliyor veya boyle bir araca gerek duymadan bir uygulama gelistiricisi olarak siz de apiye kendi uygulamanizla baglanip istediginiz sekilde verinizi kullanabilirsiniz.

Tehlike ve avantaj

Bu isin tek tehlikeli olmaya basladigi bir konu var, o da internette her yer kopya iceriklerle dolmaya baslamasi. Bunun rahatsiz edici yanini orneklemem gerekirse, her gun takip ettigim yuzlerce twitter hesabinin binlerce tweetini cok hizli sekilde okumam gerekiyor ve okudugum icerigin yarisindan fazlasi otomatik uretilen veya kopya icerik. Eger icerigi kaliteli ise bunun kotu bir yani yok. Yani mesela mashable’da post edilen bir haberi tweet’den okuyarak ulasiyorsam problem degil ama insanlarin foursquare check-inlerini gormek beni rahatsiz ediyor. Eger bu sayi okudugunuz 10 tweetin 1-2 tanesini kapsiyorsa dayanilmaz olabiliyor. Bu acidan dusunuldugunde api kullanimi her yere uymuyor. Yani bunu gereksiz kullanacak insanlar her zaman oluyor.

Fakat bunun cok guzel bir yani var, mesela cok spesifik bir konuda bir web sayfasi yapiyorsunuz ve bu sayfanin icinde twitter’da konusulan tweetleri hashtage gore sayfanizda gostermek istiyorsunuz. Cunku kullanicinin bu akisi o sayfada gormesi oldukca anlamli veya degerli olabiliyor. Insanlarin aliskin oldugu servisleri uygulamaniza entegre ederseniz sadece uygulamanizin kullanilabilirligini kolaylastirmis olmuyor ayni zamanda hazir olan icerige de ulasabiliyor oluyorsunuz. Yani konu sadece yeni icerigin dis kaynaklarda toplanmasi degil. Hatta o, isin onemsiz kismi. Mesela arkadaslik uzerine kurulu bir uygulama yapiniz var ise insanlarin facebook hesaplarina ve arkadas listesine api araciligiyla erisip kullanicinin karsisina cikarmaniz hem kullanicinin saniyeler icinde, bazen 1-2 click ile sizin ana fonksiyonunuza erismesini saglayabiliyorsunuz.

mfyz.com?

Artik neredeyse hic yazi yazmadigim mfyz.com hakkinda tabi ki planlarim var. mfyz.com’um su an gezdiginiz (v0.7) surumunu kodlarken sadece flickr apisini kullanarak tum galeri bolumunu flickra devretmistim. Bu konuda cok rahatim. Hem cok daha az kod yaziyor hem de bu bolumun yonetimi icin zaten surekli kullaniyor oldugum flickr hesabima masaustu araclarimi kullanarak cok hizli fotograf yukleyebiliyorum. Sitede gorunmesi icin o fotografa mfyz.com etiketi eklemem yetiyor. Sanirim bu ornek isin kolayligini ve avantajini iyi ornekliyor.

Ne zaman olacagini bilmiyorum ama bir sure sonra codeigniter kullanarak, test edilebilir bir kod ile, bircok dis kayanak kullanilmis bir mfyz.com hazirlamayi planliyorum. Ornek veriyorum butun yorum ve forum cevaplarini disqus ile yonetmeyi, butun resimleri yine flickr ile, dokuman iceriklerini belki bir wiki motoru ile, kullanici yonetimini codeigniter’in bir kullanici yonetimi kutuphanesi ile ya da tamamen facebook connect ve twitter oauth ile, belki arayuzdeki bazi kisimlari jquery pluginleri ile sunacagim.

Eskiden bu tarz servisleri esnek kullanabilme sansiniz yoktu. Kim ne kod verirse onu kullanmak zorunda idiniz. Ancak wordpress, thumblr gibi servisler arayuz konusunda bir motor ustunde herseyin yapilabilecegini herkese ispatladiktan sonra isler degisti. Zaten bu isin kolay kismi. Eger biraz daha zaman harcayip apileri kullanarak kendi arayuzlerinizi cizmeyi tercih ederseniz zaten bu noktada ozgun bir is cikarmamak icin tek engel kendiniz kaliyorsunuz.

Bırakın kullanıcı yorumlarını facebook halletsin

Kullanıcı yorumlarının kullanım alanları

Şu an neredeyse her şeyi internette paylaşmaya başladık. En basit kullanıcı bile birkaç saatte çeşitli araçlarla veya kendi yazarak bir web sayfası üretebiliyor. Bu sayfalarda tecrübelerini, fotograflarını paylaşıyorlar. Bu paylaşımın bir yanı da, aslında interaktif yanı diğer ziyaretçilerin içerik hakkında yorum yapması, tartışabilmesi. Bu iletişim o kadar önemli ve detaylı olmaya başladı ki, çok basit bir ruh halinizi paylaştığınız Facebook status’de bile kullanıcılar yorum yazıyorlar. Facebook yorumları ve yönetimini bu noktada oldukça başarılı şekilde yapıyor.

Son dönemde connect aracılığı ile bazı kaynaklarını dış sitelere de açmaya başladığından bu yorumlama mekanizmasını paylaştığı bir yapı var: Facebook Connect Comment Box. Bu dökümanda facebook connect ile commentbox uygulamasını herhangi bir web sayfasına nasıl entegre edeceğimizi göstereceğim.

Facebook Connect’e giriş

Facebook connect ile ilgili ana sistematiği Facebook connect ile kullanıcı giriş çıkış dökümanında anlatmıştım. Comment box kullanabilmek için facebook connect kurulumunu sayfanıza yapmanız gerekiyor. Tabiki bunun için de bir uygulama oluşturmak zorundasınız. Basitçe özetlersem :

  • “Developers” uygulamasını ekleyin
  • Kendinize yeni bir uygulama oluşturun ve bir api anahtarı edinmiş olun
  • Uygulama ayarlarında facebook connect URL olarak comment box kullanacağınız sayfanın adresini girin
  • Site ayarlarını yapmaya html etiketinize fbml sözlüğü yolunu girin
  • Facebook JS Api’nin javascript kütüphanesini include edin
  • Facebook connect init fonksiyonu ile api key’inizi belirterek facebook connect’i etkinleştirin

Bu adımlardan sonra yaptığımız şey FBML yardımı facebook connect butonu eklemek, login ise kendi fonksiyonumuzu çağırarak giriş yapmış kullanıcı aksiyonlarını belirlemek idi. Fakat şimdi bunları kullanmayacağız ve çok basit bir yolla sayfamıza yine FBML yardımı ile yorum kutusu ekleyeceğiz. Okumaya devam et “Bırakın kullanıcı yorumlarını facebook halletsin”