Skip to content

Commit 79f64b4

Browse files
committed
Update code base to IBM i PHP Toolkit 1.5.0
1 parent 9e8115f commit 79f64b4

12 files changed

+6634
-5405
lines changed

ToolkitApi/CW/cw.php

100644100755
+69-69
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,7 @@ function d($dieOutput = 'x')
1515
}
1616
die($str);
1717
}
18-
// return value from toolkit config file,
19-
// or a default value, or false if not found.
20-
/*function getConfigValue($heading, $key, $default = null) {
21-
// TODO store once in a registry or the like
22-
23-
// true means use headings
24-
$config = parse_ini_file(CONFIG_FILE, true);
25-
if (isset($config[$heading][$key])) {
26-
return $config[$heading][$key];
27-
} elseif (isset($default)) {
28-
return $default;
29-
} else {
30-
return false;
31-
}
32-
33-
} //(getConfigValue)
34-
*/
18+
3519
// create unique IPC code
3620
function makeIpc($user, $connNum = 0) {
3721
$ipcUser = ($user) ? $user : DB2_DEFAULT_USER;
@@ -46,16 +30,6 @@ function makeIpc($user, $connNum = 0) {
4630
} //(makeIpc)
4731

4832

49-
/*function logThis($msg) {
50-
$logFile = getConfigValue('log','logfile');
51-
if ($logFile) {
52-
// it's configured so let's write to it. ("3" means write to a specific file)
53-
$formattedMsg = "\n" . microDateTime() . ' ' . $msg;
54-
error_log($formattedMsg, 3, $logFile);
55-
}
56-
} //(logThis)
57-
*/
58-
5933
function splitLibObj($objName, $defaultLib = '') {
6034
// given an object name that MAY be qualified by a library and slash and perhaps a function,
6135
// such as "xxx/yyy(zzzz)".
@@ -141,7 +115,7 @@ function i5CpfError($errMsg = '', $errDesc = '')
141115
*/
142116
function noError()
143117
{
144-
// Shortcut (fewer params) when have an IBM i (AS400) code and message.
118+
// Clear any error information.
145119
i5ErrorActivity(I5_ERR_OK, 0, '', '');
146120

147121
} //(noError)
@@ -284,18 +258,20 @@ function i5_connect($host='', $user='', $password='', $options=array()) {
284258
} //(if (isset($options[CW_EXISTING_TRANSPORT_CONN])))
285259

286260

261+
287262
// check and store CW_TRANSPORT_TYPE, if given. It's optional.
288263
$transportType = ''; // empty is ok.
289-
if (isset( $options [CW_TRANSPORT_TYPE])) {
290-
$validTransports = array ('ibm_db2', 'odbc');
291-
if (!in_array($options[CW_TRANSPORT_TYPE], $validTransports)) {
264+
$iniTransportType = isset( $options [CW_TRANSPORT_TYPE]) ? $options [CW_TRANSPORT_TYPE] : getConfigValue('transport', 'transportType', 'ibm_db2');
265+
if ($iniTransportType) {
266+
$validTransports = array ('ibm_db2', 'odbc', 'http');
267+
if (!in_array($iniTransportType, $validTransports)) {
292268
// invalid transport specified.
293-
$errmsg = "Invalid CW_TRANSPORT_TYPE option ({$options[CW_TRANSPORT_TYPE]}). Omit or choose between " . explode(', ', $validTransports) . ".";
269+
$errmsg = "Invalid CW_TRANSPORT_TYPE option ({$iniTransportType}). Omit or choose between " . explode(', ', $validTransports) . ".";
294270
i5ErrorActivity ( I5_ERR_PHP_TYPEPARAM, I5_CAT_PHP, $errmsg, $errmsg );
295271
return false;
296272
} else {
297273
// valid transport
298-
$transportType = $options [CW_TRANSPORT_TYPE];
274+
$transportType = $iniTransportType;
299275
} // (if (!is_resource))
300276
} //(if (isset($options[CW_EXISTING_TRANSPORT_CONN])))
301277

@@ -333,9 +309,10 @@ function i5_connect($host='', $user='', $password='', $options=array()) {
333309
// user/pw rules
334310
// TODO share these with i5_adopt_authority
335311

336-
// forbid QSECOFR and usernames starting with *. (don’t want *CURRENT, etc.)
312+
// forbid QSECOFR and usernames starting with *. (don't want *CURRENT, etc.)
313+
// TODO Actually, not sure if QSECOFR and special profiles should be forbidden. Check again with old toolkit.
337314
if ((strtoupper($user) == 'QSECOFR') || (substr($user, 0, 1) == '*') || empty($password) || (substr($password, 0, 1) == '*')) {
338-
i5ErrorActivity(I5_ERR_WRONGLOGIN, I5_CAT_PHP, 'Bad login user or password', 'Cannot adopt authority to QSECOFR or special profiles');
315+
i5ErrorActivity(I5_ERR_WRONGLOGIN, I5_CAT_PHP, 'Bad login user or password', 'Cannot connect with QSECOFR, blank password, or special profiles');
339316
return false;
340317
} //(if QSECOFR)
341318

@@ -352,6 +329,11 @@ function i5_connect($host='', $user='', $password='', $options=array()) {
352329
$tkit = ToolkitServiceCw::getInstance($dbname, $user, $password, $transportType, $isPersistent);
353330
} //(if ($existingTransportResource))
354331

332+
// if getInstance() returned false (unlikely)
333+
if (!$tkit) {
334+
setError(I5_ERR_NOTCONNECTED, I5_CAT_PHP, 'Cannot get a connection', 'Cannot get a connection');
335+
} //(if (!$tkit))
336+
355337
} catch (Exception $e) {
356338

357339
// If user or password is wrong, give errNum I5_ERR_WRONGLOGIN with category I5_CAT_PHP.
@@ -380,6 +362,10 @@ function i5_connect($host='', $user='', $password='', $options=array()) {
380362
return false;
381363
}
382364

365+
// successfully instantiated toolkit connection and instance. Mark it as CW.
366+
$tkit->setIsCw(true);
367+
368+
383369
// override toolkit settings if nec.
384370
$sbmjobParams = getConfigValue('system', 'sbmjob_params');
385371
$xmlServiceLib = getConfigValue('system', 'XMLServiceLib', 'ZENDSVR');
@@ -407,6 +393,7 @@ function i5_connect($host='', $user='', $password='', $options=array()) {
407393
$ipc = '';
408394
logThis("Running stateless; no IPC needed. CW version $cwVersion. Service library: $xmlServiceLib");
409395
} else {
396+
// TODO does this make sense? Not stateless but not private? Any purpose to stateless setting in INI file?
410397
// Not stateless, so create an IPC
411398
// TODO this will change based on persistent/nonpersistent logic
412399
// IPC to use in separate toolkit job using just user id and unique additions in makeIpc
@@ -461,7 +448,7 @@ function i5_connect($host='', $user='', $password='', $options=array()) {
461448

462449
// set IPC and other settings
463450

464-
$serviceParams = array('InternalKey' => $ipc,
451+
$serviceParams = array('internalKey' => $ipc,
465452
'stateless' => $stateless);
466453

467454
// additional settings
@@ -473,8 +460,11 @@ function i5_connect($host='', $user='', $password='', $options=array()) {
473460
$serviceParams['sbmjobParams'] = $sbmjobParams;
474461
}
475462

476-
// these will be in addition to / overriding any params set in toolkit service constructor.
477-
$tkit->setToolkitServiceParams($serviceParams);
463+
// CW always retains data structure hierarchy (integrity) in parameters.
464+
$serviceParams['dataStructureIntegrity'] = true;
465+
466+
// these will be in addition to, or overriding, any params set in toolkit service constructor.
467+
$tkit->setOptions($serviceParams);
478468

479469
// initialize
480470
$cmdArray = array();
@@ -610,9 +600,10 @@ function i5_adopt_authority($user, $password, $connection = null)
610600
$user = strtoupper($user);
611601
$password = strtoupper($password);
612602

603+
613604
// check that username and password vars are OK.
614-
// forbid QSECOFR; and forbid usernames/pwds starting with *. (don’t want *CURRENT, etc.)
615-
if ((strtoupper($user) == 'QSECOFR') || (substr($user, 0, 1) == '*') || empty($password) || (substr($password, 0, 1) == '*')) {
605+
// forbid QSECOFR and empty password (though special values such as *NOPWDCHK are OK)
606+
if ((strtoupper($user) == 'QSECOFR') || empty($password)) {
616607
i5ErrorActivity(I5_ERR_WRONGLOGIN, I5_CAT_PHP, 'Bad login user or password', '');
617608
return false;
618609
} //(if QSECOFR)
@@ -635,13 +626,23 @@ function i5_adopt_authority($user, $password, $connection = null)
635626
<data var='handleOut' type='12b' comment='really binary data not character' />
636627
</parm>\n" .
637628
// param number 4
638-
ToolkitServiceCw::getErrorDataStructXml(4) . "\n" .
629+
ToolkitServiceCw::getErrorDataStructXml(4) . "\n";
630+
631+
if (substr($password, 0, 1) != '*') {
632+
/* No asterisk at the start, so this is an attempt at a real password,
633+
* not a special pw value starting with an asterisk such as *NOPWD, *NOPWDCHK, or *NOPWDSTS.
634+
* Therefore, include pw len and CCSID, which must be omitted if pw is a special "*" value.
635+
*/
636+
$paramXml .=
639637
"<parm io='both' comment='5. length of password. Must be equal to the actual pw length. '>
640638
<data var='pwLen' type='10i0'>$pwLen</data>
641639
</parm>
642640
<parm io='in' comment='6. CCSID of password'>
643641
<data var='pwCcsid' type='10i0'>$pwCcsid</data>
644642
</parm>";
643+
644+
} // (if (substr($password, 0, 1) != '*'))
645+
645646

646647

647648
// In case of error, look for CPFs generated by specific other programs.
@@ -895,8 +896,9 @@ function i5_command($cmdString, $input = array(), $output = array(), $connection
895896

896897
// Use slower but improved "result" (REXX) technique
897898
$result = $connection->ClCommandWithOutput($finalCmdString);
898-
899+
899900
if ($result) {
901+
900902
// Command succeeded. Set and export output variables.
901903
$exportedThem = $connection->setOutputVarsToExport($simpleParmVarArray, $result);
902904
} else {
@@ -2050,34 +2052,28 @@ function i5_data_area_read($name, $offsetOrConnection = null, $length = null, $c
20502052
return false;
20512053
}
20522054

2055+
20532056
// params OK at this point
2057+
2058+
// adjust length for "all"
2059+
$lengthToUse = $length;
2060+
if (!$length || ($length <= 0)) {
2061+
// length not provided or 0 or -1: use *ALL
2062+
$lengthToUse = '*ALL';
2063+
} //(length absent or <= 0)
2064+
20542065

20552066
// If a library (optional--slash delimited), separate it.
2056-
// use *CURLIB if no library specified
2067+
// use *LIBL if no library specified
20572068
$name = strtoupper($name);
2058-
$libAndObj = splitLibObj($name, '*CURLIB');
2069+
$libAndObj = splitLibObj($name, '*LIBL');
20592070

20602071
try {
2061-
if ($length) {
2062-
20632072
$dataAreaObj = new DataArea($connection);
20642073
$dataAreaObj->setDataAreaName($libAndObj['obj'], $libAndObj['lib']);
20652074

2066-
$value = $dataAreaObj->readDataArea($offset, $length);
2067-
} else {
2068-
// use cl command that can tolerate *ALL (full length) as an option
2069-
$cmdString = "RTVDTAARA DTAARA({$libAndObj['lib']}/{$libAndObj['obj']} *ALL)";
2070-
$input = array();
2071-
$output = array('rtnvar'=>'dataAreaValue');
2072-
2073-
$commandSuccessful = i5_command($cmdString, $input, $output);
2074-
if ($commandSuccessful) {
2075-
2076-
extract(i5_output()); //creates $dataAreaValue
2077-
$value = $dataAreaValue;
2078-
}
2075+
$value = $dataAreaObj->readDataArea($offset, $lengthToUse);
20792076

2080-
}
20812077
} catch (Exception $e) {
20822078
i5CpfError('Error reading from data area', $e->getMessage());
20832079
return false;
@@ -2144,9 +2140,9 @@ function i5_data_area_write($name, $value, $offsetOrConnection = null, $length =
21442140
// (This could be left up to users, but it's easy for us to do. See how this goes.)
21452141
$value = "'" . trim($value, "'") . "'";
21462142

2147-
// Split library (use *CURLIB if no library specified) and program names
2143+
// Split library (use *LIBL if no library specified) and program names
21482144
$name = strtoupper($name);
2149-
$libAndObj = splitLibObj($name, '*CURLIB');
2145+
$libAndObj = splitLibObj($name, '*LIBL');
21502146

21512147
$dataAreaObj = new DataArea($connection);
21522148
$dataAreaObj->setDataAreaName($libAndObj['obj'], $libAndObj['lib']);
@@ -2182,8 +2178,8 @@ function i5_data_area_delete($name, $connection = null)
21822178

21832179
// params OK at this point
21842180

2185-
// Split library (use *CURLIB if no library specified) and program names
2186-
$libAndObj = splitLibObj($name, '*CURLIB');
2181+
// Split library (use *LIBL if no library specified) and program names
2182+
$libAndObj = splitLibObj($name, '*LIBL');
21872183

21882184
$dataAreaObj = new DataArea($connection);
21892185
try {
@@ -2596,13 +2592,17 @@ function i5_objects_list($library, $name = '*ALL', $type = '*ALL', $connection =
25962592
// now call it!
25972593
// pass param xml directly in.
25982594
$retPgmArr = $connection->PgmCall($apiPgm, $apiLib, $paramXml);
2599-
2595+
//var_dump($retPgmArr);
2596+
//die;
2597+
// there's a problem parsing the output xml.
2598+
2599+
26002600
if ($connection->getErrorCode()) {
26012601
i5ErrorActivity(I5_ERR_PHP_AS400_MESSAGE, I5_CAT_PHP, $connection->getErrorCode(), $connection->getErrorMsg());
26022602
return false;
26032603
}
26042604

2605-
2605+
26062606
$retArr = $retPgmArr['io_param']['listinfo']; // 'listinfo' defined in getListInfoApiXml()
26072607
$totalRecords = $retArr['totalRecords'];
26082608
$requestHandle = $retArr['requestHandle'];
@@ -2799,7 +2799,7 @@ function i5_objects_list_close(&$list)
27992799
Return Values: Resource if OK, false if failed.
28002800
Arguments:
28012801
$name - The queue name
2802-
$description - Data description in format defined by program¬_prepare. For more, see PHP Toolkit Data Description.
2802+
$description - Data description in format defined by program_prepare. For more, see PHP Toolkit Data Description.
28032803
[$key - key size - for keyed DataQ (can be omitted)]
28042804
[$connection - Connection - result of i5_connect]
28052805
*/
@@ -3565,9 +3565,9 @@ function i5_output() {
35653565

35663566

35673567
/**
3568-
* Return version number of CW
3568+
* Return version number of CW and PHP toolkit front-end.
35693569
*/
35703570
function i5_version() {
3571-
return ToolkitServiceCw::getVersion();
3571+
return ToolkitService::getFrontEndVersion();
35723572
}
35733573

0 commit comments

Comments
 (0)