tyoshikawa1106のブログ

- Force.com Developer Blog -

SFDC:ナレッジの操作

ナレッジをApexクラス内で扱う場合、いくつかの制限がありました。

とりあえず良く使用すると思われる次の処理を確認してみました。

  • DMLクエリでのナレッジ作成
  • SOQLクエリでのナレッジ取得
  • 公開状況の更新

初期設定

ナレッジの有効化

設定のナレッジから有効化を行なって下さい。
「記事」オブジェクトと「記事の管理」オブジェクトが使用できるようになります。

記事タイプの作成

設定→ナレッジ→記事タイプから記事タイプを作成して下さい。
ナレッジのオブジェクトは記事タイプ毎に用意されます。
f:id:tyoshikawa1106:20130128065719p:plain

言語の指定

設定→ナレッジ→設定から言語を指定して下さい。
ここで日本語を指定しないとApexクラス内で日本語が使用できません。
f:id:tyoshikawa1106:20130128065912p:plain


ナレッジの作成

DMLクエリでナレッジを作成する場合は次のように行います。
公開状況(ドラフト,公開,アーカイブ)はデフォルトでドラフトが登録されるので指定の必要はありません。

/*
 * Knowledgeのデータ作成
 * @param	: なし
 * @return	: Knowledge
 */
public Knowledge__kav createKnowledge() {
	Knowledge__kav objKnowledge = new Knowledge__kav();
	// URL 名
	objKnowledge.UrlName = 'UrlName';
	// タイトル
	objKnowledge.Title = 'Title';
	// 概要
	objKnowledge.Summary = 'Summary	';
	// 言語
	objKnowledge.Language = 'ja';
	// INSERT
	insert objKnowledge;
	
	return null;
}

ナレッジの取得(ドラフト)

ナレッジ(ドラフト)の取得は次のように行います。
検索条件には公開状況(PublishStatus)と言語(Language)の指定が必ず必要になります。
公開状況はドラフト、公開、アーカイブのいずれかを指定する必要があります。
IN句等で複数指定するとエラーが発生しました。
ナレッジの記事ID(KnowledgeArticleId)は公開状況の更新時に必要な項目です。

/*
 * Knowledgeの情報取得(Draft)
 * @param	: なし
 * @return	: Knowledge
 */
public Knowledge__kav getKnowledgeIsDraft() {
	return [
		select
			Id
			,UrlName
			,Title
			,Summary
			,PublishStatus
			,KnowledgeArticleId
		from
			Knowledge__kav
		where
			PublishStatus = 'Draft'
		and
			Language = 'ja'
		and
			UrlName =: 'UrlName'
		limit 1
	];
}

ナレッジの公開状況・更新(ドラフトから公開)

公開状況をドラフトから公開に変更する場合は次のように行います。

/*
 * Knowledgeの更新(Archived)
 * @param	: ナレッジ		[prmKnowledge]
 * @return	: なし
 */
public void doUpdateKnowledgeArchived(Knowledge__kav prmKnowledge) {
	String articleId = prmKnowledge.KnowledgeArticleId;
	KbManagement.PublishingService.archiveOnlineArticle(articleId, null);
}

KbManagement.PublishingService.archiveOnlineArticleがドラフトから公開に更新するための処理として用意されています。

ナレッジの取得(公開)

ナレッジ(公開)の取得は次のように行います。

/*
 * Knowledgeの情報取得(Online)
 * @param	: なし
 * @return	: Knowledge
 */
public Knowledge__kav getKnowledgeIsOnline() {
	return [
		select
			Id
			,UrlName
			,Title
			,Summary
			,PublishStatus
			,KnowledgeArticleId
		from
			Knowledge__kav
		where
			PublishStatus = 'Online'
		and
			Language = 'ja'
		and
			UrlName =: 'UrlName'
		limit 1
	];
}

ナレッジの公開状況・更新(公開からアーカイブ)

公開状況を公開からアーカイブに変更する場合は次のように行います。

/*
 * Knowledgeの更新(Archived)
 * @param	: ナレッジ		[prmKnowledge]
 * @return	: なし
 */
public void doUpdateKnowledgeArchived(Knowledge__kav prmKnowledge) {
	String articleId = prmKnowledge.KnowledgeArticleId;
	KbManagement.PublishingService.archiveOnlineArticle(articleId, null);
}

ナレッジの取得(アーカイブ)

ナレッジ(アーカイブ)の取得は次のように行います。

/*
 * Knowledgeの情報取得(Archived)
 * @param	: なし
 * @return	: Knowledge
 */
public Knowledge__kav getKnowledgeIsArchived() {
	return [
		select
			Id
			,UrlName
			,Title
			,Summary
			,PublishStatus
			,KnowledgeArticleId
		from
			Knowledge__kav
		where
			PublishStatus = 'Archived'
		and
			Language = 'ja'
		and
			UrlName =: 'UrlName'
		limit 1
	];
}

詳細について

ナレッジの専用クラスについては次のURLで詳しく説明されています。
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_knowledge_kbManagement.htm


最後に

検証用にテストクラスを作成してみました。

@isTest
private class KnowledgeSampleControllerTest {

	/*
	 * コンストラクタ・テスト
	 */
    static testMethod void KnowledgeSampleControllerTest() {
        System.debug('◆◆◆◆KnowledgeSampleControllerTest:START');
        
        // ユーザ取得
        User objUser = getUser();
        
        // テスト実施
        System.RunAs(objUser) {
            
            // カレントページにパラメータを設定
            PageReference pageRef = getPageReference();
            Test.setCurrentPage(pageRef);
            
            // テスト開始
            Test.startTest();
            
            // コンストラクタ
            KnowledgeSampleController cls = new KnowledgeSampleController();
            
            // テスト終了
            Test.stopTest();
        }
        
        System.debug('◆◆◆◆KnowledgeSampleControllerTest:END');
    }
    
    /*
	 * Knowledgeのデータ作成・テスト
	 */
    static testMethod void createKnowledgeTest() {
        System.debug('◆◆◆◆createKnowledgeTest:START');
        
        // ユーザ取得
        User objUser = getUser();
        
        // テスト実施
        System.RunAs(objUser) {
            
            // カレントページにパラメータを設定
            PageReference pageRef = getPageReference();
            Test.setCurrentPage(pageRef);
            
            // コンストラクタ
            KnowledgeSampleController cls = new KnowledgeSampleController();
            
            // テスト開始
            Test.startTest();
            
            // Knowledgeのデータ作成
            Knowledge__kav objKnowledge = cls.createKnowledge();
            System.assertNotEquals(objKnowledge, new Knowledge__kav());
            
            // テスト終了
            Test.stopTest();
        }
        
        System.debug('◆◆◆◆createKnowledgeTest:END');
    }
    
    /*
	 * Knowledgeの情報取得・テスト
	 */
    static testMethod void getKnowledgeTest() {
        System.debug('◆◆◆◆getKnowledgeTest:START');
        
        // ユーザ取得
        User objUser = getUser();
        
        // テスト実施
        System.RunAs(objUser) {
            
            // カレントページにパラメータを設定
            PageReference pageRef = getPageReference();
            Test.setCurrentPage(pageRef);
            
            // コンストラクタ
            KnowledgeSampleController cls = new KnowledgeSampleController();
            // Knowledgeのデータ作成
            Knowledge__kav objKnowledge = cls.createKnowledge();
            
            // テスト開始
            Test.startTest();
            
            // Knowledgeのデータ取得
            Knowledge__kav objKnowledgeDraft = cls.getKnowledgeIsDraft();
            System.assertEquals(objKnowledgeDraft.PublishStatus, 'Draft');
            
            // テスト終了
            Test.stopTest();
        }
        
        System.debug('◆◆◆◆getKnowledgeTest:END');
    }
    
    /*
	 * Knowledgeの更新(Online)・テスト
	 */
    static testMethod void doUpdateKnowledgeOnlineTest() {
        System.debug('◆◆◆◆doUpdateKnowledgeOnlineTest:START');
        
        // ユーザ取得
        User objUser = getUser();
        
        // テスト実施
        System.RunAs(objUser) {
            
            // カレントページにパラメータを設定
            PageReference pageRef = getPageReference();
            Test.setCurrentPage(pageRef);
            
            // コンストラクタ
            KnowledgeSampleController cls = new KnowledgeSampleController();
            // Knowledgeのデータ作成
            Knowledge__kav objKnowledge = cls.createKnowledge();
            // Knowledgeのデータ取得
            Knowledge__kav objKnowledgeDraft = cls.getKnowledgeIsDraft();
            System.assertEquals(objKnowledgeDraft.PublishStatus, 'Draft');
            
            // テスト開始
            Test.startTest();
            
            // Knowledgeの更新(Online)
            cls.doUpdateKnowledgeOnline(objKnowledgeDraft);
            
            // テスト終了
            Test.stopTest();
        }
        
        System.debug('◆◆◆◆doUpdateKnowledgeOnlineTest:END');
    }
    
    /*
	 * Knowledgeの取得(Online)・テスト
	 */
    static testMethod void getKnowledgeIsOnlineTest() {
        System.debug('◆◆◆◆getKnowledgeIsOnlineTest:START');
        
        // ユーザ取得
        User objUser = getUser();
        
        // テスト実施
        System.RunAs(objUser) {
            
            // カレントページにパラメータを設定
            PageReference pageRef = getPageReference();
            Test.setCurrentPage(pageRef);
            
            // コンストラクタ
            KnowledgeSampleController cls = new KnowledgeSampleController();
            // Knowledgeのデータ作成
            Knowledge__kav objKnowledge = cls.createKnowledge();
            // Knowledgeのデータ取得(Draft)
            Knowledge__kav objKnowledgeDraft = cls.getKnowledgeIsDraft();
            System.assertEquals(objKnowledgeDraft.PublishStatus, 'Draft');
            // Knowledgeの更新(Online)
            cls.doUpdateKnowledgeOnline(objKnowledgeDraft);
            
            // テスト開始
            Test.startTest();
            
            // Knowledgeのデータ取得(Online)
            Knowledge__kav objKnowledgeOnline = cls.getKnowledgeIsOnline();
            System.assertEquals(objKnowledgeOnline.PublishStatus, 'Online');
            
            // テスト終了
            Test.stopTest();
        }
        
        System.debug('◆◆◆◆getKnowledgeIsOnlineTest:END');
    }
    
    /*
	 * Knowledgeの更新(Archived)・テスト
	 */
    static testMethod void doUpdateKnowledgeArchivedTest() {
        System.debug('◆◆◆◆doUpdateKnowledgeArchivedTest:START');
        
        // ユーザ取得
        User objUser = getUser();
        
        // テスト実施
        System.RunAs(objUser) {
            
            // カレントページにパラメータを設定
            PageReference pageRef = getPageReference();
            Test.setCurrentPage(pageRef);
            
            // コンストラクタ
            KnowledgeSampleController cls = new KnowledgeSampleController();
            // Knowledgeのデータ作成
            Knowledge__kav objKnowledge = cls.createKnowledge();
            // Knowledgeのデータ取得
            Knowledge__kav objKnowledgeDraft = cls.getKnowledgeIsDraft();
            System.assertEquals(objKnowledgeDraft.PublishStatus, 'Draft');
            // Knowledgeの更新(Online)
            cls.doUpdateKnowledgeOnline(objKnowledgeDraft);
            // Knowledgeのデータ取得(Online)
            Knowledge__kav objKnowledgeOnline = cls.getKnowledgeIsOnline();
            System.assertEquals(objKnowledgeOnline.PublishStatus, 'Online');
            
            // テスト開始
            Test.startTest();
            
            // Knowledgeの更新(Archived)
            cls.doUpdateKnowledgeArchived(objKnowledgeOnline);
            
            // テスト終了
            Test.stopTest();
        }
        
        System.debug('◆◆◆◆doUpdateKnowledgeArchivedTest:END');
    }
    
    /*
	 * Knowledgeの更新(Archived)・テスト
	 */
    static testMethod void getKnowledgeIsArchivedTest() {
        System.debug('◆◆◆◆getKnowledgeIsArchivedTest:START');
        
        // ユーザ取得
        User objUser = getUser();
        
        // テスト実施
        System.RunAs(objUser) {
            
            // カレントページにパラメータを設定
            PageReference pageRef = getPageReference();
            Test.setCurrentPage(pageRef);
            
            // コンストラクタ
            KnowledgeSampleController cls = new KnowledgeSampleController();
            // Knowledgeのデータ作成
            Knowledge__kav objKnowledge = cls.createKnowledge();
            // Knowledgeのデータ取得
            Knowledge__kav objKnowledgeDraft = cls.getKnowledgeIsDraft();
            System.assertEquals(objKnowledgeDraft.PublishStatus, 'Draft');
            // Knowledgeの更新(Online)
            cls.doUpdateKnowledgeOnline(objKnowledgeDraft);
            // Knowledgeのデータ取得(Online)
            Knowledge__kav objKnowledgeOnline = cls.getKnowledgeIsOnline();
            System.assertEquals(objKnowledgeOnline.PublishStatus, 'Online');
            
            // Knowledgeの更新(Archived)
            cls.doUpdateKnowledgeArchived(objKnowledgeOnline);
            
            // テスト開始
            Test.startTest();
            
            // Knowledgeのデータ取得(Archived)
            Knowledge__kav objKnowledgeArchived = cls.getKnowledgeIsArchived();
            System.assertEquals(objKnowledgeArchived.PublishStatus, 'Archived');
            
            // テスト終了
            Test.stopTest();
        }
        
        System.debug('◆◆◆◆getKnowledgeIsArchivedTest:END');
    }
    
    /*
     * ログインユーザの情報取得
     * @param	: なし
     * @return	: ユーザ
     */
    private static User getUser() {
    	return [
    		select
    			Id
    		from
    			User
    		where
    			Id =: UserInfo.getUserId()
    		limit 1
    	];
    }
    
    /*
     * テスト用ページの取得
     * @param	: なし
     * @return	: テスト用ページ
     */
    private static PageReference getPageReference() {
    	return new PageReference('TestPage');
    }
}

追記:2013-02-19

GitHubの使い方を覚えたのでソースをアップしてみました。

https://github.com/tyoshikawa1106/Apex_KnowledgeSample