Skip to content

Instantly share code, notes, and snippets.

@erobertus
Forked from lgaetz/lgaetz-tctoggle.php
Last active June 30, 2025 23:48
Show Gist options
  • Select an option

  • Save erobertus/36ed36c71a7480622a1dfa963529eeb5 to your computer and use it in GitHub Desktop.

Select an option

Save erobertus/36ed36c71a7480622a1dfa963529eeb5 to your computer and use it in GitHub Desktop.
<?php
#!/usr/bin/php
/*
* Script: lgaetz-tctoggle.php (Modified)
* Original Author: lgaetz - https://gist.github.com/lgaetz/28d41cf0ff5af1179d7840d67aae971c
* Modifications by: Eugene Robertus, 2025
*
* License: GNU GPL v3+
* This script and its modifications are distributed under the same GPL license.
* Please retain attribution to the original author when redistributing.
*/
include '/etc/freepbx.conf';
$FreePBX = FreePBX::Create();
$date = date('Y-m-d H:i:s');
echo "[{$date}] Executing lgaetz-tctoggle.php\n";
array_shift($argv);
$verbose = false;
if (isset($argv[0]) && in_array($argv[0], ['-v', '--verbose'], true)) {
$verbose = true;
array_shift($argv);
}
function show_usage() {
echo "Usage: lgaetz-tctoggle [options] <command> [<id|/pattern/>]\n";
echo "\nCommands:\n";
echo " list [pattern] List all Time Conditions; optionally filter by regex pattern\n";
echo " toggle <id|pattern> Toggle matching Time Condition(s) state\n";
echo " reset <id|pattern> Reset matching Time Condition(s) to default\n";
echo "\nOptions:\n";
echo " -v, --verbose Increase verbosity (show matched items and skipped actions)\n";
echo " -h, --help Show this help message and exit\n";
exit;
}
if (!isset($argv[0]) || in_array($argv[0], ['-h', '--help'], true)) {
show_usage();
}
function is_regex($str) {
return strlen($str) > 2 && $str[0] === '/' && substr($str, -1) === '/';
}
function find_matching_ids($pattern) {
global $FreePBX;
$all = $FreePBX->Timeconditions->listTimeconditions();
$ids = [];
$regex = substr($pattern, 1, -1);
foreach ($all as $item) {
if (@preg_match("/{$regex}/", $item['displayname'])) {
$ids[] = ['id' => $item['timeconditions_id'], 'name' => $item['displayname']];
}
}
return $ids;
}
function gettcstate_label($state) {
switch ($state) {
case null: return 'default';
case 'true': return 'Temp Match';
case 'true_sticky': return 'Perm Match';
case 'false': return 'Temp Unmatch';
case 'false_sticky': return 'Perm Unmatch';
default: return (string)$state;
}
}
function apply_action($id, $name, $action) {
global $FreePBX, $verbose;
$state = $FreePBX->Timeconditions->getState($id);
switch ($action) {
case 'toggle':
$new = ($state == 'true' || $state == 'true_sticky') ? 'false' : 'true';
$FreePBX->Timeconditions->setState($id, $new);
echo "TC #{$id} '{$name}' toggled: {$state} -> {$new}\n";
break;
case 'reset':
if ($state == null || $state == '') {
if ($verbose) echo "TC #{$id} '{$name}' is already default; skipping reset\n";
} else {
$FreePBX->Timeconditions->setState($id, null);
echo "TC #{$id} '{$name}' reset to default\n";
}
break;
}
}
$cmd = strtolower($argv[0]);
$arg = $argv[1] ?? null;
switch ($cmd) {
case 'list':
$pattern = $arg;
if ($verbose) {
echo $pattern ? "Listing Time Conditions matching {$pattern}\n" : "Listing all Time Conditions\n";
}
$list = $FreePBX->Timeconditions->listTimeconditions();
foreach ($list as $item) {
if (!$pattern || (is_regex($pattern) && preg_match($pattern, $item['displayname']))) {
printf("%-4d %-30s %s\n",
$item['timeconditions_id'],
$item['displayname'],
gettcstate_label($FreePBX->Timeconditions->getState($item['timeconditions_id'])));
}
}
break;
case 'toggle':
case 'reset':
if (!$arg) {
echo "Error: '{$cmd}' requires an ID or regex pattern\n";
exit(1);
}
$targets = [];
if (ctype_digit($arg)) {
$targets[] = ['id' => (int)$arg, 'name' => ''];
} elseif (is_regex($arg)) {
$matches = find_matching_ids($arg);
if (empty($matches)) {
echo "No time conditions match pattern {$arg}\n";
exit;
}
$targets = $matches;
} else {
echo "Invalid identifier: must be numeric ID or regex /pattern/\n";
exit(1);
}
if ($verbose) {
echo count($targets) . " target(s) for {$cmd}:\n";
foreach ($targets as $tc) {
echo " - #{$tc['id']} {$tc['name']}\n";
}
}
foreach ($targets as $tc) {
$state = $FreePBX->Timeconditions->getState($tc['id']);
if ($cmd === 'reset') {
if ($state == null || $state == '') {
if ($verbose) echo "TC #{$tc['id']} '{$tc['name']}' is already default; skipping reset\n";
continue;
}
apply_action($tc['id'], $tc['name'], $cmd);
} else {
apply_action($tc['id'], $tc['name'], $cmd);
}
}
break;
default:
echo "Unknown command: {$cmd}\n";
show_usage();
}
@erobertus
Copy link
Author

lgaetz-tctoggle.php Improvements

1. Regex-based Selection

  • Accepts regex patterns (enclosed in /…/) as arguments for list, toggle, and reset commands
  • Filters time conditions by name using regular expressions

2. Verbose Mode (-v, --verbose)

  • Displays matched conditions before taking action
  • Reports skipped actions when a condition is already in the desired state
  • Provides context for each operation (e.g., listing, toggling, resetting)

3. Enhanced Usage Help (-h, --help)

  • Full description of commands, arguments, and options
  • Clear usage synopsis at invocation or on error

4. Safe Action Execution

  • toggle and reset only perform state changes when needed
  • Skips operations on conditions already in target state (with optional verbose notice)

5. Improved Output Formatting

  • Lists both ID and display name of time conditions
  • Action feedback includes the condition’s name for easier identification

6. Streamlined Argument Parsing

  • Supports flags and positional arguments order-insensitively
  • Shifts script name and options cleanly before command dispatch

7. Robust Error Handling

  • Validates numeric IDs versus regex patterns
  • Graceful exit with helpful messages on invalid input

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment