Skip to main content

Complete SDK Integration Guide

Comprehensive API reference and integration guide for all CjForum SDKs.

Table of Contents​

Profile System API​

Complete reference for user profiles, avatars, and profile links.

getProfile()​

Get complete user profile data.

Signature:

public function getProfile(
int|array|null $userId = null,
bool $forPublic = true,
bool $forceReload = false
): array|null

Parameters:

  • $userId - User ID (int), array of IDs, or null for current user
  • $forPublic - Format for public display (default: true)
  • $forceReload - Force reload from database (default: false)

Returns: Profile array or null if not found

Example:

// Single user
$profile = $profileApi->getProfile(42);
// Returns: ['id' => 42, 'name' => 'John Doe', 'username' => 'john', ...]

// Multiple users
$profiles = $profileApi->getProfile([42, 43, 44]);
// Returns: [42 => [...], 43 => [...], 44 => [...]]

// Current user
$myProfile = $profileApi->getProfile();

getAvatar()​

Get avatar HTML with optional profile link.

Signature:

public function getAvatar(
int|array $userId,
int $size = 48,
array $attributes = [],
bool $withLink = true
): string|array

Parameters:

  • $userId - User ID or array of IDs
  • $size - Avatar size in pixels (default: 48)
  • $attributes - HTML attributes for avatar element
  • $withLink - Include profile link wrapper (default: true)

Returns: Avatar HTML string or array of HTML strings

Example:

// Basic usage
$avatar = $profileApi->getAvatar(42);
// Returns: <a href="..."><img src="..." alt="John Doe" /></a>

// Custom size
$avatar = $profileApi->getAvatar(42, 128);

// With custom CSS class
$avatar = $profileApi->getAvatar(42, 64, ['class' => 'rounded-circle']);

// Without link
$avatar = $profileApi->getAvatar(42, 48, [], false);

// Multiple users
$avatars = $profileApi->getAvatar([42, 43, 44], 64);

getAvatarUrl()​

Get avatar URL only (no HTML).

Signature:

public function getAvatarUrl(int|array $userId, int $size = 48): string|array

Example:

$url = $profileApi->getAvatarUrl(42, 128);
// Returns: "https://example.com/images/avatars/user-42.jpg"

Get profile link HTML.

Signature:

public function getProfileLink(
int|array $userId,
?string $linkText = null,
array $attributes = []
): string|array

Parameters:

  • $userId - User ID or array of IDs
  • $linkText - Link text (null = use username)
  • $attributes - HTML attributes for link element

Example:

// Default (uses username)
$link = $profileApi->getProfileLink(42);

// Custom text
$link = $profileApi->getProfileLink(42, 'View Profile');

// With attributes
$link = $profileApi->getProfileLink(42, null, ['class' => 'btn btn-primary']);

searchUsers()​

Search for users by name or username.

Signature:

public function searchUsers(string $query, int $limit = 10, array $options = []): array

Example:

$results = $profileApi->searchUsers('john', 5);
// Returns array of matching users

getUserStats()​

Get user statistics (topics, replies, points, etc.).

Signature:

public function getUserStats(int $userId): ?array

Example:

$stats = $profileApi->getUserStats(42);
// Returns: ['topics' => 150, 'replies' => 1250, 'points' => 5000, ...]

prefetchProfiles()​

Prefetch user profiles for batch operations (performance optimization).

Signature:

public function prefetchProfiles(array $userIds): void

Example:

$userIds = [42, 43, 44, 45];
$profileApi->prefetchProfiles($userIds);

// Now these calls are instant
foreach ($userIds as $userId) {
$profile = $profileApi->getProfile($userId);
}

Points System API​

Complete reference for awarding points, leaderboards, and rankings.

awardPoints()​

Award points to a user for a specific rule.

Signature:

public function awardPoints(
string $ruleId,
int $userId = 0,
int $points = 0,
$reference = null,
?string $title = null,
?string $description = null
): bool

Parameters:

  • $ruleId - Unique rule identifier (e.g., 'com_myblog.new_article')
  • $userId - User ID (0 = current user)
  • $points - Points amount (0 = use rule default)
  • $reference - Reference ID to prevent duplicates
  • $title - Custom title (null = use rule title)
  • $description - Custom description (null = use rule description)

Example:

// Basic usage
$pointsApi->awardPoints('com_myblog.new_article', $userId, 10);

// Prevent duplicate awards
$pointsApi->awardPoints('com_myblog.read_article', $userId, 5, $articleId);

// Custom title and description
$pointsApi->awardPoints(
'com_myblog.featured_article',
$userId,
50,
null,
'Featured Article',
'Your article was featured on the homepage'
);

getUserPoints()​

Get user's total points.

Signature:

public function getUserPoints(int|array|null $userId = null): int|array

Example:

// Single user
$total = $pointsApi->getUserPoints(42);

// Multiple users
$points = $pointsApi->getUserPoints([42, 43, 44]);
// Returns: [42 => 150, 43 => 200, 44 => 75]

// Current user
$myPoints = $pointsApi->getUserPoints();

getPointsHistory()​

Get user's points history/transactions.

Signature:

public function getPointsHistory(
int $userId = 0,
int $limit = 20,
int $offset = 0
): array

Example:

$history = $pointsApi->getPointsHistory($userId, 20);

foreach ($history as $transaction) {
echo $transaction['title'] . ': ' . $transaction['points'] . ' points';
}

getUserRank()​

Get user's rank position.

Signature:

public function getUserRank(int $userId = 0): int

Example:

$rank = $pointsApi->getUserRank($userId);
echo "User rank: #{$rank}";

getTopUsers()​

Get top users by points.

Signature:

public function getTopUsers(int $limit = 10): array

Example:

$topUsers = $pointsApi->getTopUsers(10);

foreach ($topUsers as $user) {
echo $user['name'] . ': ' . $user['points'] . ' points';
}

registerRulesFromXml()​

Register points rules from XML file.

Signature:

public function registerRulesFromXml(string $xmlPath): bool

Example XML:

<?xml version="1.0" encoding="UTF-8"?>
<cjforum>
<points_rule>
<name>com_myblog.create_article</name>
<appname>com_myblog</appname>
<title>Create Article</title>
<description>Points for creating a new article</description>
<points>10</points>
<state>1</state>
<auto_approve>1</auto_approve>
<access>1</access>
</points_rule>
</cjforum>

Example:

$xmlPath = JPATH_ADMINISTRATOR . '/components/com_myblog/cjforum_rules.xml';
$pointsApi->registerRulesFromXml($xmlPath);

prefetchUserPoints()​

Prefetch points for multiple users (performance optimization).

Signature:

public function prefetchUserPoints(array $userIds): void

Activity Stream API​

Complete reference for activity feeds, likes, and comments.

push()​

Push an activity to the stream.

Signature:

public function push(object $activity): bool

Activity Object Properties:

  • type (required) - Activity type (e.g., 'com_myblog.new_article')
  • title (required) - Activity title
  • description (required) - Activity description
  • user_id (optional) - User ID (default: current user)
  • item_id (optional) - Related item ID
  • parent_id (optional) - Parent item ID
  • featured (optional) - Is featured? (default: 0)
  • language (optional) - Language code (default: '*')
  • length (optional) - Truncate description to length

Example:

$activity = (object) [
'type' => 'com_myblog.new_article',
'title' => 'New Article Published',
'description' => 'User published an article about Joomla',
'user_id' => $userId,
'item_id' => $articleId,
'featured' => 0,
'length' => 200
];

$streamApi->push($activity);

getStream()​

Get activity stream items with filters.

Signature:

public function getStream(array $filters = [], int $limit = 20, int $offset = 0): array

Filter Options:

  • user_id - Filter by user
  • type - Filter by activity type
  • item_id - Filter by item
  • parent_id - Filter by parent
  • featured - Show only featured
  • language - Filter by language

Example:

// Get latest activities
$activities = $streamApi->getStream([], 20);

// Filter by type
$articles = $streamApi->getStream(['type' => 'com_myblog.new_article'], 20);

// Filter by user
$userActivities = $streamApi->getStream(['user_id' => 42], 20);

// Multiple filters
$filters = [
'type' => 'com_myblog.new_article',
'featured' => true,
'language' => 'en-GB'
];
$featured = $streamApi->getStream($filters, 10);

likeActivity() / unlikeActivity()​

Like or unlike an activity.

Example:

// Like an activity
$streamApi->likeActivity($activityId, $userId);

// Unlike an activity
$streamApi->unlikeActivity($activityId, $userId);

addComment()​

Add a comment to an activity.

Signature:

public function addComment(int $activityId, string $comment, int $userId = 0): int|bool

Example:

$commentId = $streamApi->addComment($activityId, 'Great article!', $userId);

getComments()​

Get comments for an activity.

Example:

$comments = $streamApi->getComments($activityId, 20);

foreach ($comments as $comment) {
echo $comment['author_name'] . ': ' . $comment['description'];
}

registerActivityTypesFromXml()​

Register activity types from XML file.

Example XML:

<?xml version="1.0" encoding="UTF-8"?>
<cjforum>
<activity_type>
<name>com_myblog.new_article</name>
<appname>com_myblog</appname>
<title>New Article</title>
<alias>new-article</alias>
<description>User published a new article</description>
<published>1</published>
<access>1</access>
<language>*</language>
</activity_type>
</cjforum>

Integration Patterns​

Pattern 1: Complete Blog Integration​

<?php
namespace Joomla\Component\Myblog\Site\Controller;

use Joomla\CMS\MVC\Controller\FormController;
use Joomla\Component\CjForum\Site\CjForum;

class ArticleController extends FormController
{
public function save($key = null, $urlVar = null)
{
$result = parent::save($key, $urlVar);

if ($result && CjForum::isAvailable())
{
$articleId = $this->input->getInt('id');
$userId = $this->app->getIdentity()->id;
$title = $this->input->getString('title');

// Award points
CjForum::points()->awardPoints(
'com_myblog.create_article',
$userId,
10,
$articleId
);

// Push to stream
$activity = (object) [
'type' => 'com_myblog.new_article',
'title' => 'New Article Published',
'description' => $title,
'item_id' => $articleId
];
CjForum::stream()->push($activity);
}

return $result;
}
}

Pattern 2: User Profile Card​

<?php
use Joomla\Component\CjForum\Site\CjForum;

if (CjForum::isAvailable()):
$profileApi = CjForum::profile();
$pointsApi = CjForum::points();

$profile = $profileApi->getProfile($userId);
$points = $pointsApi->getUserPoints($userId);
$rank = $pointsApi->getUserRank($userId);
$stats = $profileApi->getUserStats($userId);
?>
<div class="user-card">
<?php echo $profileApi->getAvatar($userId, 96); ?>
<h3><?php echo $profileApi->getProfileLink($userId); ?></h3>
<p><?php echo $this->escape($profile['about']); ?></p>
<ul class="stats">
<li>Points: <?php echo $points; ?> (Rank #<?php echo $rank; ?>)</li>
<li>Topics: <?php echo $stats['topics']; ?></li>
<li>Replies: <?php echo $stats['replies']; ?></li>
</ul>
</div>
<?php endif; ?>

Pattern 3: Activity Feed​

<?php
use Joomla\Component\CjForum\Site\CjForum;

if (CjForum::isAvailable()):
$streamApi = CjForum::stream();
$profileApi = CjForum::profile();

$activities = $streamApi->getStream([], 10);

// Prefetch author profiles
$userIds = array_unique(array_column($activities, 'created_by'));
$profileApi->prefetchProfiles($userIds);
?>
<div class="activity-feed">
<?php foreach ($activities as $activity): ?>
<div class="activity-item">
<?php echo $profileApi->getAvatar($activity['created_by'], 48); ?>
<div class="activity-content">
<h4><?php echo $activity['title']; ?></h4>
<p><?php echo $activity['description']; ?></p>
<div class="activity-meta">
<?php echo $profileApi->getProfileLink($activity['created_by']); ?>
• <?php echo $activity['likes']; ?> likes
• <?php echo JHtml::_('date', $activity['created']); ?>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>

Performance Optimization​

1. Always Prefetch for Lists​

// ❌ BAD - N queries
foreach ($items as $item) {
$avatar = $profileApi->getAvatar($item->user_id);
$points = $pointsApi->getUserPoints($item->user_id);
}

// ✅ GOOD - 2 queries
$userIds = array_column($items, 'user_id');
$profileApi->prefetchProfiles($userIds);
$pointsApi->prefetchUserPoints($userIds);

foreach ($items as $item) {
$avatar = $profileApi->getAvatar($item->user_id);
$points = $pointsApi->getUserPoints($item->user_id);
}

2. Batch Operations​

// Get data for multiple users at once
$userIds = [42, 43, 44, 45];

$profiles = $profileApi->getProfile($userIds);
$points = $pointsApi->getUserPoints($userIds);
$avatars = $profileApi->getAvatar($userIds, 64);

3. Single Availability Check​

// Check once, use multiple times
if (CjForum::isAvailable()) {
$profileApi = CjForum::profile();
$pointsApi = CjForum::points();
$streamApi = CjForum::stream();

// Use all three APIs
}

Error Handling​

Graceful Degradation​

try {
if (!CjForum::isAvailable()) {
// CjForum not installed - use fallback
echo '<span>' . $username . '</span>';
return;
}

$profileApi = CjForum::profile();
$profile = $profileApi->getProfile($userId);

if ($profile === null) {
// User not found
echo '<span>Unknown User</span>';
return;
}

// Display with CjForum data
echo $profileApi->getAvatar($userId, 64);

} catch (\RuntimeException $e) {
// CjForum not available
error_log('CjForum SDK error: ' . $e->getMessage());
echo '<span>' . $username . '</span>';

} catch (\Exception $e) {
// Other errors
error_log('Unexpected error: ' . $e->getMessage());
echo '<span>' . $username . '</span>';
}

Check Before Use​

// Always check availability
if (CjForum::isAvailable()) {
// Safe to use
$profileApi = CjForum::profile();
} else {
// Provide alternative
}

See Also​

Support​