24 Şubat 2009 Salı

Sharepoint Survey EditForm.aspx nasıl editlenir?

Uğrastığım proje kapsamında Sharepoint'in anket yapısını customize etmem gerektiğinden bahsetmiştim. Sharepoint'in yapısı gereği ankete başladıgınızda bulundugunuz Anketin New Form.aspx sayfası, ankette ilerleyip başka bir soru için sayfa atladığınızda EditForm.aspx sayfası yüklenir. Benden her sayfaya ankette soruların % kaçı cevaplandıgına dair bir progress bar koymam istendi. NewForm.aspx ilk soru için çalışacağı için ilk sayfada %0 yazmasında bir sakınca yoktu. Fakat ankette dallanma sonucu başka bir sayfaya yönlendiğimizde EditForm.aspx sayfası yükleniyor. Burdaki mantık aslında gayet basit.. Ilk soru için NewForm.aspx'in çalısmasının sebebi Sharepoint anketine yeni bir cevap giriyor olmamız. Yani listeye yeni bir item giriyoruz dolayısıyla diğer tüm listelerde oldugu gibi NewForm.aspx sayfasıyla item olusturuluyor. Daha sonraki her cevabımızda kendi olusturdugumuz list item'ı editlemiş oluyoruz. Neyse bu kısa ön bilgiden sonra konumuza dönelim...

Öncelikle EditForm.aspx sayfası yüklendiğinde FirstField parametresinin içi o sayfada görüntülenecek ilk soru bilgisiyle dolar(EditForm.aspx?FirstField=naber gibi).
Bütün bu sorular anketimizin fieldlarına 0 indexinden başlayarak ekleniyor.Standart bir anketin 43 tane field ı oldugunu bildiğimize göre mevcut anketin field sayısından 43 ü çıkararak kaç tane soru oldugunu bulabiliyoruz.
FirstField QueryString değerini okuyarak da Sayfada görüntülenecek ilk soru değerini(Bu da anketin bir fieldına tekabül ediyor) alabiliyoruz. Bu ilk sorunun yani anket fieldının, anket fieldlarında kaçıncı sırada oldugunu bulup bunu toplam soru adetine oranlayarak anketin % kaçına geldiğini bulabiliyoruz kullanıcımızın. Mevzu kısaca bu, pek kısa olmadı gerçi.. Neyse Kodumu da açıklayıcı olması açısından aşağıya koyuyorum.

using System;using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
namespace TTEIMWebControls.UserControls.AnketCustomization
{public partial class AnketProgressBar : System.Web.UI.UserControl
{protected void Page_Load(object sender, EventArgs e)
{if (!this.IsPostBack)
{string firstField=Request.QueryString["FirstField"].ToString();
if (!firstField.Equals(string.Empty)){
string anketName = GetAnketName();
SPWeb curWeb = SPContext.Current.Web;
SPField field = curWeb.Lists[anketName].Fields.GetFieldByInternalName(firstField);
bool fieldExists = CheckField(field, curWeb.Lists[anketName]);
if (!fieldExists){
SPList anketList = curWeb.Lists[anketName];
/*each Question created by the user is added as a field, that's why we get the number ofquestions by subtracting the number of already existing fields from the total field count*/

int totalSoru = anketList.Fields.Count - 43;
int index = 1;/*we get the current question's index by iterating over the list's fields from* the start and break the loop whenever we find that question field*/
foreach (SPField fieldI in anketList.Fields){
if (fieldI.InternalName.Equals(firstField))
break;
index++;
}
int mevcutSoruİndex = index;
double percentage = ((double)100 / totalSoru) * index;

}
}
}
}


Bu user controlümüzü C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\CONTROLTEMPLATES dizini altına kopyalıyıp ilgili dll'i GAC'a deploy ediyoruz. Sonrasında Sharepoint Designer yardımıyla sitemize bağlanıp istediğimiz Anket'in EditForm. aspx 'inin içerisine register edip yerleştiriyoruz. Bundan sonra yarattıgımız anketlerin bu EditForm.aspx'i kullanmasını istiyorsak mevcut Anketimizi şablon olarak kaydedip bundan sonraki anketlerimizi bu şablondan yaratabiliriz.
Hepinize iyi çalışmalar..

23 Şubat 2009 Pazartesi

Go Mongo Adında bir Restaurant

Madem blog kişiye özel bir olgu, o zaman bende biraz özel hayatımdan ufak tefek ipuçları vererek sizlerle hayatımı paylaşayım.
Doğumgünüm 6 Temmuz'da babamın ısrarları sonucu Suadiye'deki Moğol restoranı Go Mongo ile tanıştım. Başta Moğolistanın İngilizcedeki karşılığı olan Mongolia(Mongolistan) ülkesinin yemekleriyle tanısacak olmanın yarattıgı garip ruh hali, doğumgünümün boka sarmasından duydugum endişe ve masada karşılaşabileceğim ne işe yarayacağını bile tahmin edemeyeceğim sayıda çatal kaşıkla dolu kasıcı bir gece yasama çekinceleriyle girdim Go Mongo'nun kapısından. Gerçekten şaşırtıcı derecede hos bir ambiyansı var mekanın. Yaz olması dolayısıyla terasta oturduk. Yemek öncesi birşeyler içebileceğiniz bir barı var. Genelde rezervasyon yapmayanların ayakta kaldıgı bu mekanda bi barın bulunması da fena fikir olmamış açıkçası. Yemek olarak babamın tavsiyesi üzerine Mongolian Barbeque tercih ettim. Değişik bir konsept...
Size verilen tabağı, barbekü büfesinde tıka basa doldurabiliyorsunuz.
Barbekü büfesinde neler yok ki.. Dana eti, kuzu eti, tavuk, levrek,karides, aklınıza gelebilecek her türlü sebze ve garnitür. Tabi bütün bunlar pişmemiş durumda. Kendi kombinasyonunuzu yapıyorsunuz ve büfenin bir diğer ucunda sizi güler yüzle bekleyen kızın yanında alıyorsunuz soluğu. Elindeki noodle dolu bardağın üstüne aldıgınız etlere uygun bir sos belirliyorsunuz beraberce ve tahminimce mekanı Moğol yapan pişirme bölümüne geçiyorsunuz. Kombinasyonunuz daha evvel karşılaşmadıgım ilginç bir tezgahta pişiyor ve istediğiniz takdirde pişerken zevklen izleyebiliyorsunuz yemeğinizi. 5-10 dk sonrasında o muhteşem lezzetle tanısma fırsatını yakalıyorsunuz. Gerçekten enfes:P. Bu benim fikrim elbette.. Sizi en mutlu edecek kombinasyonu yakalamanız belki biraz zaman alabilir ama tahminimce her Go Mongo'ya gittiğinizde yüzünüzde mutlu bir tebessümle beni anacaksınız.
Su anda gece yarısı ve acıktım, acilen hiç olmazsa bir dürüm atıştırmam lazım, Kalın sağlıcakla..

if(Sendikalasma==null) {developer.Surun();}

Bugünkü yazımda Developerlar olarak içinde bulundugumuz büyük tehlikeye karsı birazcık duyarlılıgımızı arttırmamızın şart oldugu konusundan dem vuracağım. Nedir bu büyük tehlike?
Yıllardır süregelen bir durum olmasına rağmen bu kadar eğitilmiş insanın kendini savunmak için tek bir harekette bulunmamasını anlamakta güçlük çekiyorum. Milyon dolarlık projeler 2-3 developerın özverili çalısması sonucu 10-15 günde bitirilirken, bu developerların hayatları büyük sekteye uğruyor. Gece ofislerde sabahlamalar, dengesiz beslenme, uyku düzeninin bozulması, saatlerce maruz kalınan radyasyon sonucu bilimum hastalık ihtimali, Gözlerde ortaya çıkan ışığa karsı hassasiyet ve bence en ağır olanı sömürülmeye karsı bu kadar tepkisiz kalmak. Yani sonuçta bu bir alışverişse alanın da verenin de bu takastan memnun ayrılması gerekirken, çevremde mutlu developer görmekte güçlük çekiyorum. Bilişim öğrencileri yetiştiren kurum furyasının yükselmesi sonucu işverenler bunu bir koz olarak kullanıp ya çalısırsın ya da senin yerine çalışacak birini buluruz felsefesini benimsemiş durumda. Peki biz developerlar olarak bu kadar savunmasız olmayı kabullenecek miyiz?
Bence Hayır. Bu işin tek çözümü bu bireyselliklerimizi bir kenara koyup birimiz hepimiz için olmaktan geçiyor. Sendikalaşıp standartlarımızı yukarı çekmeye, insan olarak yasam kalitemizi bu kadar ayaklar altına aldırmamaya mecburuz. Bu Yazı ne kadar çok developera ulasırsa bu konuda yapabileceklerimiz konusunda bi o kadar pozitif feedback alabileceğimizi düşünüyorum. Yorumlarınızı ilgiyle bekliyorum.
Kalın Sağlıcakla

19 Şubat 2009 Perşembe

MOSS 2007'nin temel taşı: CAML Query

MOSS 2007 verilerini listeler aracılıgıyla tutar. En basitinden herhangi bir sayfa bile Pages listesinin itemlarındandır. MOSS 2007 ile gelen listeler WSS 'de varolan listeler ve kullanıcının kendi olusturdugu listeler olmak üzere dataların saklandıgı bir çok liste tipi mevcuttur. Peki bu listelerden verileri alıp kod tarafında bir takım işlemler uygulayıp göstermek için bu listelere nasıl sorgu atabiliriz?
Bunun için 2 tane yolumuz var. Bunlar web servisi yardımıyla atılacak sorgular ve daha yaygın olanı obje modelini kullanarak atılacak sorgulardır. Bu sorgularda kullanılan dil olan CAML (Collaborative Application Markup Language), Sharepoint ürünlerinde kullanılan xml tabanlı bir dildir. CAML sorguları olusturmak çoğu zaman zahmetli olacağı için u2u firması, CAML Query Builder isimli, yaygın olarak kullanılan bir ürün çıkarmıştır. linkinden bu ürüne ulasabilirsiniz.

Bu blogumda basit bir CAML Liste sorgusu örneği vererek sizlere bir start vermek istiyorum. Bu örnek için bir Console Application olusturuyoruz. Bu uygulamamızda Rating kontrolüyle puanlanan Sayfaların Url'lerinin ve verilen Puanların tutuldugu Puanlar isimli listemizden 3 puan verilen itemları getirmeye çalısacağız.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;

namespace ConsoleTest
{
class Program
{
static void Main(string[] args)
{
using(SPSite site=new SPSite("http://eelkabes:600"))
{
using(SPWeb currentWeb=site.OpenWeb())
{
//Puanlar listemizi SPList tipindeki lstPuanlar değişkenimize atıyoruz
SPList lstPuanlar = currentWeb.Lists["Puanlar"];
// Listeyi sorgulamak için kullancağımı SPQuery sınıfından bir instance yaratıyoruz
SPQuery query = new SPQuery();
//Puanlar Listesinden Puan Field değeri 3 olan itemları getirecek sorgumuzu olusturuyoruz
query.Query = @" <Where>
<Eq>
<FieldRef Name='Puan' />
<Value Type='Number'>3</Value>
</Eq>
</Where>";
//SPList sınıfının GetItems metoduna SPQuery objemizi parametre olarak vererek listemizi sorguluyoruz
SPListItemCollection items=lstPuanlar.GetItems(query);

//Sonuç kümemiz içerisinde dolaşarak Puanlanan Item'in URL alanının değerini Console'da gösteriyoruz
foreach (SPListItem item in items)
{
Console.WriteLine(item["URL"]);
}
Console.ReadLine();
}
}
}
}
}


Kodumuz bu kadar. CAML'a böylece giriş yapmış olduk. Bir sonraki blogumda Sharepoint Web Servisleri yardımıyla sorgular olusturup kayıtları sorgulayacağız ve update edebiliyor olacağız. Bir sonraki blogumda görüşmek üzere...

MOSS 2007'de user controlleri kullanmak

Sharepoint'de user controllerini pagelerde göstermenin bir çok yolu var. En çok kullanılanı Hollandalı üstat Jan Tielens'in son of smartpart, return of smartpart gibi bir takım türevleri olan web partını koyup bu web partta görüntülenmesini istediğiniz user controlleri smartpartın istediği klasöre kopyalamak ve dll'i gac a basmak. Bu işlem basit gözüküyor, fakat bu toolu kullanmadan da user controlleri sharepoint pagelerine koyabilirmiyiz sorusuna cevap ararken su anda çalıstıgım projedeki danısmanım Nezih Tınas çok basit başka bir yöntem göstererek bir nevi ufkumu genişletti. Ne demişler, bana bir kelime öğretenin bin yıl kulu kölesi olurum diye, kendisiyle yıldızımız çoğu zaman barısmasa da teşekkürlerimi sunuyorum kendisine ve yazdıgı ilk Türkçe MOSS kitabını okumanızı tavsiye ediyorum. tıklayarak kitap hakkında daha fazla bilgi alabilirsiniz. Neyse biz konumuza dönelim fazla dağılmadan. User controlümüzü olusturduktan sonra yapacağımız hareket ascx uzantılı dosyamızı C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\CONTROLTEMPLATES klasörünün altına koymak vace ilgili dll'i ya GAC'a ya da bine kopyalayıp web.configde ilgili dll'leri register etmek.

Daha sonra kullandıgım en kötü tool olmasına rağmen rakibi olmaması sebebiyle kullanmak zorunda oldugumuz Sharepoint Designer yardımıyla portalimize erişip bir sayfaya bu kontrolü register ederek yola devam ediyoruz

<%@ Register TagPrefix="tteim" TagName="GS" Src="~/_controltemplates/TTEIM/AnketGirisUserControl.ascx" %> //AnketGirisUserControlümüzü register ediyoruz.

Ve en son olarak da
bu kontrolümüzü form taglarının arasına yerleştirerek misyonumuzu tamamlıyoruz.


Bundan sonra sitenizde kontrolü yerleştirdiğimiz sayfaya giderek user controlümüzü görebiliriz

Timer Job Nasıl Install edilir?

bir önceki blogumda MOSS'da bir timer jobun nasıl yazılacağından bahsetmiştim. Peki bu jobu nasıl install ederiz? Ne zamanlarda çalısacağını nasıl belirtiriz?
Bu blogumda bu konulara açıklık getirmek istiyorum. Bir önceki blogumda yazdıgım jobu install ederek başlayalım. Bu jobu bir FeatureReceiver yazarak deploy etmek en kullanıslı yoldur. SPFeatureReceiver classından türeyen bir sınıf yaratıp, bu abstract sınıfın metodlarını implement ediyoruz.

class ProfileBasedReportInstaller:SPFeatureReceiver
{
const string TASK_LOGGER_JOB_NAME = "My Reporting Job"; //jobumuzun central administrationdaki joblar arasında görülecek ismi

public override void FeatureInstalled(SPFeatureReceiverProperties properties)
{
}

public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
{
}

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPWeb web = properties.Feature.Parent as SPWeb;

// make sure the job isn't already registered
foreach (SPJobDefinition job in web.Site.WebApplication.JobDefinitions)
{
if (job.Name == TASK_LOGGER_JOB_NAME)
job.Delete();
}

// install the job
DailyProfileBasedRatingReportJobDefinition myjob = new DailyProfileBasedRatingReportJobDefinition(TASK_LOGGER_JOB_NAME, web.Site.WebApplication); //jobumuzdan bir instance yaratıyoruz

//jobumuzun çalısacağı zamanları set ediyoruz
SPMinuteSchedule schedule = new SPMinuteSchedule();
schedule.BeginSecond = 1;
schedule.EndSecond = 59;
schedule.Interval = 1;
myjob.Schedule = schedule;

myjob.Update();
}


İşte jobumuz için bu featureReceiver ı yazdıktan sonra yapmamız gereken iş C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES klasöründe yeni bir folder olusturarak feature.xml imizi içine koymak.
Feature.xml imizin içinde feature ımızın receiver classını ve receiver Assemblysini yazmamız yeterli olacaktır.

Örnek feature.xml için kendi feature.xml imin içeriğini aşağıya kopyalıyorum.


18 Şubat 2009 Çarşamba

MOSS 2007'de Timer Job nasıl Yazılır?

Uğrastıgım proje kapsamında yarattıgımız MOSS portali kullanıcılarının portaldeki sayfaları Ajax Control Toolkit'in rating kontrolüyle oylamaları ve bu oyların Puanlar isimli bir listede URL, Puan gibi custom sütunlar olusturularak tutulması isteniyordu. Burada ilginç birşey yok, fakat isteğin devamında günlük bir sharepoint jobun çalısarak bir excel dosyasına listedeki itemları yazdırması ve yazdırırken Oylayan kullanıcının Profilinden de bazı bilgileri çekerek onları da yazması isteniyordu.
Sharepoint timer jobu yazmak için ilk yapılması gereken Microsoft.Sharepoint.Administration namespace'inde bulunan SPJobDefinition classından türeyen bir sınıf yaratmak.

class DailyProfileBasedRatingReportJobDefinition:SPJobDefinition
{
Workbook book;
Worksheet sheet;
WorksheetRow row;
public DailyProfileBasedRatingReportJobDefinition()
: base()
{
}

public DailyProfileBasedRatingReportJobDefinition(string name, SPService service, SPServer server, SPJobLockType jlt)
: base(name, service, server, jlt)
{
}

public DailyProfileBasedRatingReportJobDefinition(string name, SPWebApplication webApp)
: base(name, webApp, null, SPJobLockType.None)
{
this.Title = name;
}
public override void Execute(Guid targetInstanceId)
{
SPSite siteCollection = (this.Parent as SPWebApplication).Sites["/"];
SPList lstPuanlar = siteCollection.RootWeb.Lists["Puanlar"];
//Yapmamız gerekenleri yapıyoruz. Tüm kodu vermek isterdim, fakat hukuki olaylarla uğrasmak istemediğimden bunlan yetinmek zorundayız
}
}

Bu SPJobDefinition classının Execute Metodunu override ederek job çalıstıgında ne yapması gerekiyorsa onları burada yapıyoruz.


Peki simdi bu jobu nasıl install ederiz?
Cevabı bir sonraki blogumda bulacaksınız.
Keep Watchin'..

MOSS 2007'de anketin Özelleştirilmesi

Bu ilk blogumda daha evvel değinilmemiş bir konuya değinerek başlamak istiyorum. Bulundugum proje kapsamında MOSS'un özel listelerinden "Anket" listesini özelleştirmem istendi. Olusturulacak anketlerin bir giriş yazısı, bir teşekkür yazısı olması isteniyordu. Anketi dolduracak kişileri olusturacağım giriş sayfasına yollamak bir sorun değildi, fakat anketin bittiğini nasıl anlayıp son sorudan sonra kullanıcıyı teşekkür sayfasına gönderecektim? Mevcut anket listesinde böyle bir özellik olmadıgından custom bir Anketler isminde liste yaratarak işe başladım. Bu listede Giriş yazısı, Teşekkür yazısı, Anket Adı, Url kolonlarını olusturdum. Anket olusturmak isteyen yetkili kimse önce bu listeye bir item ekleyerek işe başlayacaktı. Yazdıgım ItemEventReceiver'in itemAdded metodunu override ederek işe başladım. Bu metod kullanıcının girdiği anket adına göre benim özelleştirdiğim anket Template inden bir anket yaratacak ve bu anketin Url ini set edecekti.


class AnketItemEventReceiver : SPItemEventReceiver
{
public override void ItemAdded(SPItemEventProperties properties)
{
SPWeb currentWeb = properties.OpenWeb();
SPListItem item = properties.ListItem;
currentWeb.AllowUnsafeUpdates = true;
SPFieldUrlValue urlValue = new SPFieldUrlValue();
urlValue.Description = "Anket Url";

urlValue.Url = currentWeb.Url + "/Lists/" + item["Anket_x0020_Ad_x0131_"].ToString() + "/overview.aspx";
item["Url"] = urlValue;
item.Update();

SPListTemplate objTemplate = currentWeb.Site.GetCustomListTemplates(currentWeb.Site.RootWeb)["Anket Şablonu"];

Guid objGuid = currentWeb.Lists.Add(item["Anket_x0020_Ad_x0131_"].ToString(), "survey", objTemplate);
}
}

Bu ilk blogumda herseyi anlatmayıp merakı canlı tutmak adına bana verilen bu taskı gerçekleştirmek için yaptıgım diğer hareketleri bir sonraki bloguma saklıyorum. Bu blogumla beraber bir ItemEventReceiver'in nası yazılacağı, Sharepoint object model yardımıyla olusturulan bir şablondan programatik olarak bir liste yaratılmasını görmüş olduk.
Bir sonraki blogumda görüşmek üzere