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