Index data with Solr PHP Client - php

I'm using the Solr PHP Client and have the Solr 4.3.0 example up and running. I have not modified the schema.xml file. When I run this code I get a 400 error:
Uncaught exception 'Apache_Solr_HttpTransportException' with message '400' Status: Bad Request.'
The document does not show up in the index. Interestingly, If I restart Jetty, the document is indexed. Here's my code. I was wondering if I'm missing something. I thought this was an issue with my input matching the schema, but id seems to be the only required field and these other fields are in the schema. I'm not sure what to do.
require_once('SolrPhpClient/Apache/Solr/Service.php');
$solr = new Apache_Solr_Service('localhost', 8983, '/solr/');
if($solr->ping() == null){
die('could not ping solr');
}
$document = new Apache_Solr_Document();
$document->id = 'guid1';
$document->title = 'Title1';
$document->subject = 'The subject is solr';
$document->description = 'This is the description';
$solr->addDocument($document);
$solr->commit();
The full error message I get is
Fatal error: Uncaught exception 'Apache_Solr_HttpTransportException' with message ''400' Status: Bad Request' in C:\xampp\htdocs\dev\SolrPhpClient\Apache\Solr\Service.php:364
Stack trace:
#0 C:\xampp\htdocs\dev\SolrPhpClient\Apache\Solr\Service.php(829): Apache_Solr_Service->_sendRawPost('http://localhos...', '<commit expunge...', 3600)
#1 C:\xampp\htdocs\dev\indexerSOLR_PHP.php(20): Apache_Solr_Service->commit()
#2 {main} thrown in C:\xampp\htdocs\dev\SolrPhpClient\Apache\Solr\Service.php on line 364`

This is a known issue with Solr 4.x and calling commit from the Solr PHP Client. Please see
Bug #62332 - As of solr 4.0 the waitFlush parameter is removed for commit for the details and a patch to fix the issue.

That is what how I got the solution, I modified commit method. Added '&commit=true' to the _updateurl variable.
public function commit($expungeDeletes = false, $waitFlush = true, $waitSearcher = true, $timeout = 3600)
{
$expungeValue = $expungeDeletes ? 'true' : 'false';
$flushValue = $waitFlush ? 'true' : 'false';
$searcherValue = $waitSearcher ? 'true' : 'false';
//$rawPost = '<commit expungeDeletes="' . $expungeValue . '" waitFlush="' . $flushValue . '" waitSearcher="' . $searcherValue . '" />';
//$this->post=$rawPost;
return $this->_sendRawGet($this->_updateUrl.'&commit=true', $timeout);
}

You have change this line.
require_once('SolrPhpClient/Apache/Solr/Service.php'); => require_once('Service.php');
Maybe Service.php this file's path wrong. I try to changed this line. Then work successfully.

I had the same issue because I have installed an old version of the PHP Solr extension (0.9.11).
To get a the latest one:
pecl download solr-beta
tar xvzf solr-2.1.0.tgz # This can be different depending on the last release number
cd solr-2.1.0/
phpize
./configure
make
sudo make install
# add extension=solr.so to your php.ini / distribution extension loader
Thanks to this post.

Related

Read Windows Installer (MSI file) attributes from PHP

I have a Windows MSI file, that I need to programmatically read the version number from. The only place I can see this version is within the Subject of the file details:
If I somehow can read the entire content of Subject this would be fine but is there any way to get this from PHP? The PHP is running in an IIS web server, if this helps ;-)
stat is of no help for this.
I considered doing a checksum of the file, and can do that, but I really need the real version.
For now I am unable to find a native PHP solution for this, so I have temporarily solved this by calling a Powershell script as it seems easier to do in there.
I am now having this PHP code:
$version = exec("powershell.exe -file GetMsiVersion.ps1 MyFile.msi);
With my above picture then $version will contain 1.5.9, so I will not even require to interpret the data from Subject.
The GetMsiVersion.ps1 Powershell script has this code:
function Get-Property ($Object, $PropertyName, [object[]]$ArgumentList) {
return $Object.GetType().InvokeMember($PropertyName, 'Public, Instance, GetProperty', $null, $Object, $ArgumentList)
}
function Invoke-Method ($Object, $MethodName, $ArgumentList) {
return $Object.GetType().InvokeMember($MethodName, 'Public, Instance, InvokeMethod', $null, $Object, $ArgumentList)
}
$Path = $args[0]
$msiOpenDatabaseModeReadOnly = 0
$Installer = New-Object -ComObject WindowsInstaller.Installer
$Database = Invoke-Method $Installer OpenDatabase #($Path, $msiOpenDatabaseModeReadOnly)
$View = Invoke-Method $Database OpenView #("SELECT Value FROM Property WHERE Property='ProductVersion'")
Invoke-Method $View Execute
$Record = Invoke-Method $View Fetch
if ($Record) {
Write-Output (Get-Property $Record StringData 1)
}
Invoke-Method $View Close #()
I will accept this as the best solution here-and-now but, I hope this can be archieved natively from PHP as I see this as a better and more clean solution - and by then I will accept that as the best answer (or at least unaccept my own temporary solution).
Doing an exec is a little evil ;-)
Two things first:
I have never accessed COM from PHP, but below are some VBScript samples of getting information from MSI files by using MSI API - COM automation. There are also Win32 functions.
That field you refer to is not a version field, but a text field from the MSI's "Summary Stream" - a special part of the MSI file with "meta information" of various kinds. Summary Information Stream (the full name).
Here is how you can get the REAL version of an MSI file. This is stored in the property "ProductVersion" in the MSI file. There are at least two different ways to retrieve it - by opening the MSI file as a session or just access the property table via SQL query:
Access version via Session object:
Const msiUILevelNone = 2
Dim installer : Set installer = CreateObject("WindowsInstaller.Installer")
installer.UILevel = msiUILevelNone
Set s = installer.OpenPackage("C:\MySetup.msi",1)
MsgBox CStr(s.ProductProperty("ProductVersion"))
Accessing version via SQL agains MSI database (property table):
Dim installer : Set installer = CreateObject("WindowsInstaller.Installer")
' Open MSI database in read-only mode (0)
Set db = installer.OpenDatabase("C:\MySetup.msi", 0)
Set view = db.OpenView("SELECT `Value` FROM `Property` WHERE `Property`='ProductVersion'")
view.Execute
Set record = view.Fetch
MsgBox CStr(record.StringData(1))
Then there is the issue of accessing the SummaryStream - which is what you are really asking by the looks of it - here is a simple smoke test with some hints as to what properties you can retrieve - be careful with the summary stream - corruption is possible in various ways (I don't recall the details, but it should be safe to access read-only):
Dim installer : Set installer = CreateObject("WindowsInstaller.Installer")
' Open MSI database in read-only mode (0)
Set db = installer.OpenDatabase("C:\MySetup.msi", 0)
MsgBox CStr(db.SummaryInformation.Property(3))
' 1 = "Codepage"
' 2 = "Title"
' 3 = "Subject"
' 4 = "Author"
' 5 = "Keywords"
' 6 = "Comments"
' 7 = "Template"
' 8 = "LastAuthor"
' 9 = "Revision"
' 11 = "Printed"
' 12 = "Created"
' 13 = "Saved"
' 14 = "Pages"
' 15 = "Words"
' 16 = "Characters"
' 18 = "Application"
' 19 = "Security"
Links:
Modify an MSI using MSI SQL VBScript WiRunSQL.vbs
List tables in MSI file using VBScript

Google Cloud Vision - PHP Error occurred during parsing

Im using Vision API Client Library for PHP.
This is my code:
use Google\Cloud\Vision\V1\ImageAnnotatorClient;
putenv("GOOGLE_APPLICATION_CREDENTIALS=/json.json");
$imageAnnotator = new ImageAnnotatorClient();
$fileName = 'textinjpeg.jpg';
$image = file_get_contents($fileName);
$response = $imageAnnotator->labelDetection($image);
$labels = $response->getLabelAnnotations();
if ($labels) {
echo("Labels:" . PHP_EOL);
foreach ($labels as $label) {
echo($label->getDescription() . PHP_EOL);
}
} else {
echo('No label found' . PHP_EOL);
}
And I receive this error:
Error occurred during parsing: Fail to push limit. (0)
/srv/www/site.ru/htdocs/vendor/google/protobuf/src/Google/Protobuf/Internal/CodedInputStream.php:345
#0: Google\Protobuf\Internal\CodedInputStream->pushLimit(integer)
/srv/www/site.ru/htdocs/vendor/google/protobuf/src/Google/Protobuf/Internal/CodedInputStream.php:368
#1: Google\Protobuf\Internal\CodedInputStream->incrementRecursionDepthAndPushLimit(integer, integer, integer)
....
....
....
#15: Google\Cloud\Vision\V1\ImageAnnotatorClient->labelDetection(string)
/srv/www/site.ru/htdocs/local/php_interface/GoogleCloud.php:41
This is the place, where Exception goes from:
public function pushLimit($byte_limit)
{
// Current position relative to the beginning of the stream.
$current_position = $this->current();
$old_limit = $this->current_limit;
// security: byte_limit is possibly evil, so check for negative values
// and overflow.
if ($byte_limit >= 0 &&
$byte_limit <= PHP_INT_MAX - $current_position &&
$byte_limit <= $this->current_limit - $current_position) {
$this->current_limit = $current_position + $byte_limit;
$this->recomputeBufferLimits();
} else {
throw new GPBDecodeException("Fail to push limit.");
}
return $old_limit;
}
$byte_limit <= $this->current_limit - $current_position is true
Should I increase current_position? And if I should, how can i do it? Change something on server or in PHP config?
It's a crazy thing to do!
The error "Fail to push limit" appears from time to time in forums. Various ideas are given there as to where the problem could lie. One cause could be when the source code is composed on the local PC via Composer and then transferred to the server via (S)FTP. The FTP programme decides on the basis of the file extension whether it saves the data on the server in ASCII or binary format.
In vendor/google/protobuf/src/Google/Protobuf/ there are various generated files that have a .php extension but are actually BINARY! (if you open the file, you can see it immediately, e.g. : vendor/google/protobuf/src/GPBMetadata/Google/Protobuf/Any.php)
The solution to transfer these files explicitly via binary to the server worked in my case! If in doubt, transfer the complete module from Google/protobuf as a binary...
You mentioned that $byte_limit <= $this->current_limit - $current_position is true, so either $byte_limit >= 0 or $byte_limit <= PHP_INT_MAX - $current_position are false.
If $byte_limit <= PHP_INT_MAX - $current_position is false, then increasing $current_position, won't turn it true. If you want to tweak the values, so the expression get evaluated as true, you would need to increase the value of PHP_INT_MAX instead.
If $byte_limit >= 0 is false, then modifying $current_limit won't avoid the exception.
Either way, it seems that the error is an issue with the protobuf php library, so I'd recommend you to report the issue there, rather than try to modify the values directly.
mbstring.func_overload was 2
This was the reason of error
Changed to 0 and it worked

GRAV git-sync plugin update crashing web-site, has anyone encountered/solved?

I've been using GRAV as a CMS for a small experimental site. I recently updated the git-sync plugin, and am suddenly stuck with a website that produces only errors, with no way to enter the admin gui (all web access to the site crashes with same errors), to downgrade the git-sync module, or for that matter, to upgrade the git-sync plugin if there is a fix.
I'm a developer that hasn't really thought much about web development in decades (my, how it's changed), so there are a few things I have to admit upfront. I don't know sht about php, and really don't care to if I don't have to.
The message I get (below) indicates that this is a php error. If this is a simple syntax fix please give me a heads up.
If you have any advice on a "cli" way to use the git-sync plugin to upgrade or downgrade, revert the git-sync, or any other hints, advise away. I'll dig in to more documentation and see if I end up answering my own question.
/[pathToUserHome]/grav/user/plugins/git-sync/classes/GitSync.php
*/
$paths = ['.'];
if (version_compare($version, '2.0', '<')) {
$add .= ' --all';
}
return $this->execute($add . ' ' . implode(' ', $paths));
}
public function commit($message = '(Grav GitSync) Automatic Commit')
{
$authorType = $this->getGitConfig('author', 'gituser');
if (defined('GRAV_CLI') && in_array($authorType, ['gravuser', 'gravfull'])) {
$authorType = 'gituser';
}
// get message from config, it any, or stick to the default one
$message = $this->getConfig('git', null)['message'] ?? $message;
// get Page Title and Route from Post
$pageTitle = $_POST['data']['header']['title']??'NO TITLE FOUND';
$pageRoute = $_POST['data']['route']??'NO ROUTE FOUND';
...
Arguments
1) "syntax error, unexpected '?'"
Whoops\Exception\ErrorException…
/user/plugins/git-sync/classes/GitSync.php : 223
$message = $this->getConfig('git', null)['message'] ?? $message;
Your new version of GRAV is using php7.0 features, like ?? operator, which is Null coalescing. Try to upgrade your php version to support new features, or downgrade GRAV.
Make a compatible version is also an option, but it could be time consumption idea. However, if your problems only in this particular file, you could replace:
// $message = $this->getConfig('git', null)['message'] ?? $message;
$message = isset($this->getConfig('git', null)['message']) ? $this->getConfig('git', null)['message'] : $message;
// $pageTitle = $_POST['data']['header']['title']??'NO TITLE FOUND';
$pageTitle = isset($_POST['data']['header']['title']) ? $_POST['data']['header']['title'] : 'NO TITLE FOUND';
// $pageRoute = $_POST['data']['route']??'NO ROUTE FOUND';
$pageRoute = isset($_POST['data']['route']) ? $_POST['data']['route'] : 'NO ROUTE FOUND';

PHP Connect to Sharepoint using Thybag\SharePointAPI

I have the following code
//$sp = new SharePointAPI('&&', '&&', 'https://&&.net/personal/zzz/_vti_bin/Lists.asmx?WSDL',);
//$sp = new SharePointAPI('&&', '&&', 'https://&&net/personal/zzz/_vti_bin/Lists.asmx?SDL', 'NTLM');
$sp = new SharePointAPI('&&', '&&', 'https://&&net/personal/zzz/_vti_bin/Lists.asmx?WSDL', 'SPONLINE');
$listContents = $sp->read('GetListCollection');
return $listContents;
Depending on which of the "new SharepointAPI" lines I execute, I get a different error.
Using "NTLM", I get the error: -
Uncaught exception 'Exception' with message 'Error'
in /home/shinksyc/public_html/sharepointUpload/src/Thybag/Auth/SoapClientAuth.php:129
Stack trace:
#0 [internal function]: Thybag\Auth\SoapClientAuth->__doRequest('<?xml
version="...', 'https://my.sp.m...', 'http://schemas....', 1, 0)
Using "SPONLINE", I get the error
'Error (Client) looks like we got no XML document'.
I am also slightly confused as to how to find out what the name of the lists may be that I get read.
Any help is much appreciated.
Thanks
Martin
The path to your xml must be local: in clear, log to your sharepoint, go to the url https://mySPsite/subsite/_vti_bin/Lists.asmx?WSDL
Download the XML and place it on your PHP server.
then
$sp = new SharePointAPI($login, $password, $localPathToWSDL, 'NTLM');

Uncaught exception 'Zend_Cache_Exception' with message 'cache_dir must be a directory'

I am new to Zend and I have to work on previously done project to add some functionality.
Below are the cache specifications in application.ini file.
cache.frontend.type = Core
cache.frontend.options.lifetime = 7200
cache.frontend.options.automatic_serialization = true
cache.frontend.options.cache_id_prefix = proj_name
cache.frontend.options.cache = true
cache.backend.type = Memcached
cache.backend.options.servers.1.host = 127.0.0.1
cache.backend.options.servers.1.port = 11211
cache.backend.options.servers.1.persistent = true
cache.backend.options.servers.1.weight = 1
cache.backend.options.servers.1.timeout = 5
cache.backend.options.servers.1.retry_interval = 15
logsdb.params.dbname = dataLink
I have installed memcache and it works fine. But the following error occurs when I want to start project.
Uncaught exception 'Zend_Cache_Exception' with message 'cache_dir must be a directory'
I tried to find some answers in google but none of the solutions worked. Please help me with this. I work on WAMP 2.1
Not sure, but if you use an "new" version of Zend Framework (1.8+?), than you have to use
CacheManager in your application.ini to setup the cache.
For memcache it should look like this:
resources.cachemanager.myache.frontend.name = Core
resources.cachemanager.mycache.frontend.options.automatic_serialization = On
resources.cachemanager.mycache.backend.name = Memcached
resources.cachemanager.mycache.backend.options.servers.1.host =
resources.cachemanager.mycache.backend.options.servers.1.port = 1
resources.cachemanager.mycache.backend.options.servers.2.host =
resources.cachemanager.mycache.backend.options.servers.2.port =
And somewhere in your Controller to get the Cache:
$cacheManager = $this->getInvokeArg('bootstrap')->getResource('cachemanager');
$myCache = $cacheManager->getCache('mycache');
Or anyhwhere in your code (i dont like this way)
$cacheManager = Zend_Controller_Front::getInstance()
->getParam('bootstrap')
->getResource('cachemanager');
$myCache = $cacheManager->getCache('mycache');

Categories