# Personality Profile Cycles Analysis

**Date**: January 27, 2026  
**System**: World Numerology API (WNAPI)  
**Focus**: Period Cycles & Pinnacle Cycles in Personality Profiles

---

## 📊 Overview

The personality profile contains **two major cycle systems**:
1. **Period Cycles** (PageID: 10)
2. **Pinnacle Cycles** (PageID: 16)

Both cycles are calculated from the user's birth date and are used to determine life phases and their meanings.

---

## 🔄 PERIOD CYCLES (PageID: 10)

### What Are Period Cycles?
Period Cycles divide a person's life into three major phases, each with a specific numeric value that influences personality and life direction.

### Data Flow

```
Birth Date Input
    ↓
calculate_periodscycles($day, $month, $year) - Line 313
    ↓
$periodcycle array [4 values: index, first, second, third]
    ↓
Database Query (Lines 3045-3051)
    ├─ SELECT from personality_output_text_details WHERE pagetype_id=10
    └─ SELECT from personality_header_details WHERE pagetype_id=16
    ↓
Loop through data['THE PATH AND YOU']
    ├─ Check for "First Period Cycle"
    ├─ Check for "Second Period Cycle"
    └─ Check for "Third Period Cycle"
    ↓
Display with Dynamic Content
```

### Code Location
**File**: `/var/www/html/wnapi/pdf-files-app/generatehtml.php`  
**Lines**: 3043-3099  
**Function**: `generate_personality_html()`

### Key Variables

| Variable | Source | Purpose |
|----------|--------|---------|
| `$periodcycle` | `calculate_periodscycles()` | Array with 4 cycle values |
| `$data[$key][$key1]` | Database result | Numeric value for each period cycle |
| `$val[$i]` | DB query line 3047 | Text descriptions for cycles |
| `$change[1], $change[2]` | `calculate_changes()` | Age markers (life phase boundaries) |

### Display Structure

```php
// For each period cycle:
1. Header: $headerrow[$i]['header_text']
2. Intro: $headerrow[$i]['chapter_intro']
3. Subheader with placeholders:
   - ~first~ → $original_report_first_name
   - ~AGE01~ → $change[1]
   - ~AGE02~ → $change[1] + 27
   - ~1stprcyc~ → $data[$key][$key1]
   
4. Image: <img src="imagepath/{cycle_number}.png">
5. Text Description: $val[$i]['text'.$data[$key][$key1]]
```

### Output Example

```
FIRST PERIOD CYCLE
Your First Period Cycle is 5, and runs from birth until approximately age X

[Image of number 5]

Your First Period Cycle is a 5, which means you will be exploring new ideas, 
meeting new people, new environments and experiences...
```

### Filters
**Line 3069**: Topics can be disabled via filter
```php
if (isset($topics['period_cycles']) && $topics['period_cycles'] === 0) {
    // Skip displaying period cycles
}
```

---

## 🏔️ PINNACLE CYCLES (PageID: 16)

### What Are Pinnacle Cycles?
Pinnacle Cycles represent four major life phases (typically spanning 9 years each in adulthood). They show themes and challenges during specific age ranges.

### Data Flow

```
Birth Date Input + Life Path Number
    ↓
Calculate Life Path (from $data['THE PATH YOU\'RE ON']['Your Life Path'])
    ↓
Extract last digit: $teee = end(explode("/", Life_Path))
    ↓
Calculate Age Ranges
    ├─ Age1 = 36 - $teee (End of First Pinnacle)
    ├─ Age2 = Age1 + 9 (End of Second Pinnacle)
    ├─ Age3 = Age2 + 9 (End of Third Pinnacle)
    └─ Age4+ = from Age3 until death
    ↓
Database Query (Lines 3103-3113)
    ├─ SELECT from personality_output_text_details WHERE pagetype_id=16
    └─ SELECT from personality_header_details WHERE pagetype_id=16
    ↓
Check for Repeating Cycles (Lines 3132-3172)
    ├─ If same number appears in multiple pinnacles
    ├─ Add special message: "you are repeating your X Pinnacle Cycle"
    └─ Skip text description when repeating
    ↓
Display with Age Ranges
```

### Code Location
**File**: `/var/www/html/wnapi/pdf-files-app/generatehtml.php`  
**Lines**: 3101-3226  
**Function**: `generate_personality_html()`

### Key Variables

| Variable | Source | Purpose |
|----------|--------|---------|
| `$data[$key][$key1]` | DB result | Numeric value (1-9) for each pinnacle |
| `$repeat_pinnaclearray` | Line 3116 | Array tracking all pinnacle numbers |
| `$rep_val` | Line 3134 | Count of repeated numbers |
| `$change[1-4]` | `calculate_changes()` | Age transition points |
| `$teee` | Life Path extraction | Used to calculate First Pinnacle end age |
| `$age1, $age2, $age3` | Calculated line 3194-3196 | Age boundaries for each pinnacle |

### Repeat Cycle Detection Logic (Lines 3132-3172)

```php
// Step 1: Collect all pinnacle values
$repeat_pinnaclearray = [First, Second, Third, Fourth pinnacle numbers]

// Step 2: Count occurrences
$rep_val = array_count_values($repeat_pinnaclearray)
// Example: [5 => 2, 3 => 1, 7 => 1] means 5 appears twice

// Step 3: For each pinnacle, check if it's a repeat
if ($rep_val[$value1] > 1 && $rep_value != $j) {
    // This pinnacle number repeats!
    $rep_value = array_search($value1, $repeat_pinnaclearray, true)
    // Set message based on which pinnacle is being repeated
}

// Step 4: Build message
if ($rep_value != $j) {
    if ($rep_value == 0) $rep_text = " you are repeating your First Pinnacle Cycle"
    elseif ($rep_value == 1) $rep_text = " you are repeating your Second Pinnacle Cycle"
    // etc...
}
```

### Age Range Calculation (Lines 3194-3200)

```php
// Life Path example: "9/5" → extract last digit = 5
$teee = 5

// Calculate First Pinnacle ends at age:
$age1 = 36 - 5 = 31

// Subsequent pinnacles add 9 years each
$age2 = 31 + 9 = 40
$age3 = 40 + 9 = 49
$age4+ = 49 until death

// Formula: age_range = 36 - last_digit_of_life_path
// Then add 9 years for each subsequent phase
```

### Display Structure

```php
// For each pinnacle:
1. Header: $headerrow[$i]['header_text']
2. Intro: $headerrow[$i]['chapter_intro']
3. Age Range (Lines 3202-3213):
   - If $i == 1: "...and runs from birth until approximately age {$age1}"
   - If $i == 2: "...and runs from age {$age1} until age {$age2}"
   - If $i == 3: "...and runs from age {$age2} until age {$age3}"
   - If $i == 4: "...and runs from age {$age3} until age death."

4. Conditional Display:
   - If REPEATING: Show "John you are repeating your X Pinnacle Cycle"
   - If NOT repeating: Show image + text description
```

### Output Example

```
FIRST PINNACLE CYCLE
Your First Pinnacle Cycle is a 5, and runs from birth until approximately age 31

[Image of number 5]

Your First Pinnacle Cycle is a 5, which brings opportunity for adventure, 
change, variety and freedom...

---

SECOND PINNACLE CYCLE
Your Second Pinnacle Cycle is a 5, and runs from age 31 until age 40

John you are repeating your First Pinnacle Cycle
(No additional text because it's a repeat)
```

### Filters
**Line 3139**: Topics can be disabled via filter
```php
if (isset($topics['pinnacle_cycles']) && $topics['pinnacle_cycles'] === 0) {
    // Skip displaying pinnacle cycles
}
```

---

## 🔌 Database Connection Points

### personality_output_text_details Table
Stores descriptions for each number (1-9) in each cycle type.

**Structure for Period Cycles (PageID: 10)**:
- `section_id`: 1, 2, 3 (First, Second, Third Period Cycle)
- `text1` through `text9`: Descriptions for each numeric value
- `pagetype_id`: 10

**Structure for Pinnacle Cycles (PageID: 16)**:
- `section_id`: 1, 2, 3, 4 (First, Second, Third, Fourth Pinnacle Cycle)
- `text1` through `text9`: Descriptions for each numeric value
- `pagetype_id`: 16

### personality_header_details Table
Stores headers and introductions.

**For Period Cycles (PageID: 10)**:
- `header_text`: "First Period Cycle", "Second Period Cycle", etc.
- `chapter_intro`: General introduction text
- `subheader`: Template with replaceable tags (~first~, ~AGE01~, etc.)

**For Pinnacle Cycles (PageID: 16)**:
- `header_text`: "First Pinnacle Cycle", etc.
- `subheader`: Template with tags (~chng01~, ~chng02~, etc.)

---

## 🎯 Key Differences Between Cycles

| Feature | Period Cycles | Pinnacle Cycles |
|---------|--------------|-----------------|
| **Count** | 3 phases | 4 phases |
| **Duration** | Variable (27 years total) | Variable (typically 9 years each, except first) |
| **Age Calculation** | From Life Path digit | From Life Path digit (36 - last digit) |
| **Database PageID** | 10 | 16 |
| **Repeat Detection** | ❌ No | ✅ Yes (lines 3134-3172) |
| **Special Messages** | None | "You are repeating your X Cycle" |
| **Section IDs** | 1, 2, 3 | 1, 2, 3, 4 |

---

## 🔍 Debugging/Analysis Checklist

### For Period Cycles
- [ ] Check `$periodcycle` array is populated from `calculate_periodscycles()`
- [ ] Verify database has data in `personality_output_text_details` with `pagetype_id=10`
- [ ] Confirm `$change[1]` and `$change[2]` are calculated correctly
- [ ] Verify image files exist: `/images/Images4NumbersAndLetters/{1-9}.png`
- [ ] Check filter is not disabling period_cycles

### For Pinnacle Cycles
- [ ] Verify Life Path extraction: `$teee = end(explode("/", $data['THE PATH YOU\'RE ON']['Your Life Path']))`
- [ ] Check age calculation: `$age1 = 36 - $teee`
- [ ] Confirm repeat array is built correctly (line 3116)
- [ ] Verify `$rep_val = array_count_values()` works properly
- [ ] Check message generation logic (lines 3150-3172)
- [ ] Ensure conditional display ($rep_text check at line 3208) works
- [ ] Verify filter is not disabling pinnacle_cycles
- [ ] Confirm image files exist for each pinnacle number

---

## 🐛 Common Issues

### Period Cycles Not Showing
1. Database filter: Check if `topics['period_cycles'] === 0`
2. Missing data: Verify `personality_header_details` and `personality_output_text_details` have PageID=10 records
3. Age calculation: Ensure `$change` array is properly populated

### Pinnacle Cycles Showing Incorrectly
1. Repeat detection fails: Check `array_count_values()` logic
2. Age ranges wrong: Verify Life Path extraction (last digit extraction)
3. Formula wrong: 36 - last_digit_of_life_path should give first pinnacle end age
4. Messages not showing: Check `$rep_text` condition at line 3208

### Both Cycles Showing Wrong Text
1. Font issue: Check `style=\"font-family: {$font_family};\"` is applied
2. Comma issue: Fixed - commas removed from line 3211 and 2943
3. Text not found: Verify text keys match in database (text1, text2, ... text9)

---

## 📈 Recent Code Changes

**Date**: January 27, 2026

### Fixed Issue: Misaligned Commas
- **Line 2943**: Removed comma after `$report_first_name` in Challenge section
- **Line 3211**: Removed comma after `$original_report_first_name` in Pinnacle Cycle section
- **Impact**: Display now shows "John you are repeating..." instead of "John, you are repeating..."

### Font System Updates
- **Lines 3090, 3219, 3273**: Added `style=\"font-family: {$font_family};\"` to period and pinnacle cycle descriptions
- **Impact**: Font selection now applies to all cycle content

---

## 🔗 Related Functions

| Function | Location | Purpose |
|----------|----------|---------|
| `calculate_periodscycles()` | Not shown (external) | Calculates period cycle numbers |
| `calculate_cycles()` | Line 314 | Processes period cycle values |
| `calculate_changes()` | Not shown (external) | Calculates age milestones |
| `name_replace()` | Not shown (external) | Replaces ~first~ placeholders |
| `period_name_replace()` | Not shown (external) | Replaces cycle-specific placeholders |

---

## 📋 Summary

**Period Cycles** (3 phases):
- Simple linear display
- Age boundaries: 27 years / 3 = 9 years each
- No repeat detection
- Located at Lines 3043-3099

**Pinnacle Cycles** (4 phases):
- Complex repeat detection logic
- Dynamic age calculation from Life Path
- Special messaging for repeating cycles
- Conditional text display (skip when repeating)
- Located at Lines 3101-3226

Both systems pull text from database based on numeric values (1-9) and display images + descriptions for each phase.
